@halcyonlabs/app 0.47.0-halcyon.21 → 0.47.0-halcyon.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/dist/assets/{AddMachineDialog-4BQFC118.js → AddMachineDialog-BlVfh9PM.js} +1 -1
- package/app/dist/assets/AddMachineDialog-BlVfh9PM.js.br +0 -0
- package/app/dist/assets/AddMachineDialog-BlVfh9PM.js.gz +0 -0
- package/app/dist/assets/{AppCommandShortcutHint-BlXOfa_n.js → AppCommandShortcutHint-C1mIupNX.js} +1 -1
- package/app/dist/assets/{AppFileExternalNavigationDispatcher-fGD_vTns.js → AppFileExternalNavigationDispatcher-zdrgMBvF.js} +1 -1
- package/app/dist/assets/AppFileExternalNavigationDispatcher-zdrgMBvF.js.br +0 -0
- package/app/dist/assets/AppFileExternalNavigationDispatcher-zdrgMBvF.js.gz +0 -0
- package/app/dist/assets/{AppToasterView-DzbjTKdn.js → AppToasterView-C6IQDk4H.js} +1 -1
- package/app/dist/assets/{BbDiff-BkqgAZD9.js → BbDiff-CORXfK92.js} +1 -1
- package/app/dist/assets/BbDiff-CORXfK92.js.br +0 -0
- package/app/dist/assets/BbDiff-CORXfK92.js.gz +0 -0
- package/app/dist/assets/{BbDiffSplit-DTvWaW-n.js → BbDiffSplit-By8A1QN-.js} +2 -2
- package/app/dist/assets/BbDiffSplit-By8A1QN-.js.br +0 -0
- package/app/dist/assets/BbDiffSplit-By8A1QN-.js.gz +0 -0
- package/app/dist/assets/{BbSourceCode-Dqw4VrLu.js → BbSourceCode-C3we2GZp.js} +1 -1
- package/app/dist/assets/BbSourceCode-C3we2GZp.js.br +0 -0
- package/app/dist/assets/BbSourceCode-C3we2GZp.js.gz +0 -0
- package/app/dist/assets/{BrowserTabDeck-CuHEyZd6.js → BrowserTabDeck-BtVycavD.js} +1 -1
- package/app/dist/assets/BrowserTabDeck-BtVycavD.js.br +0 -0
- package/app/dist/assets/BrowserTabDeck-BtVycavD.js.gz +0 -0
- package/app/dist/assets/{CommandPaletteBody-DynxiDg6.js → CommandPaletteBody-JfQwJqGn.js} +1 -1
- package/app/dist/assets/CommandPaletteBody-JfQwJqGn.js.br +0 -0
- package/app/dist/assets/CommandPaletteBody-JfQwJqGn.js.gz +0 -0
- package/app/dist/assets/{DiffHost-3UTZIJNs.js → DiffHost-DEYVmsVa.js} +1 -1
- package/app/dist/assets/DiffHost-DEYVmsVa.js.br +0 -0
- package/app/dist/assets/DiffHost-DEYVmsVa.js.gz +0 -0
- package/app/dist/assets/{ExperimentalFileLinkMenu-C0RXVabs.js → ExperimentalFileLinkMenu-B-B8GXE8.js} +1 -1
- package/app/dist/assets/ExperimentalFileLinkMenu-B-B8GXE8.js.br +0 -0
- package/app/dist/assets/ExperimentalFileLinkMenu-B-B8GXE8.js.gz +0 -0
- package/app/dist/assets/{FilePreview-BxgJ2jjI.js → FilePreview-BHoPmg-c.js} +1 -1
- package/app/dist/assets/FilePreview-BHoPmg-c.js.br +0 -0
- package/app/dist/assets/FilePreview-BHoPmg-c.js.gz +0 -0
- package/app/dist/assets/{GitDiffCardHeader-Ce736y-m.js → GitDiffCardHeader-6LP_7oWh.js} +1 -1
- package/app/dist/assets/GitDiffCardHeader-6LP_7oWh.js.br +0 -0
- package/app/dist/assets/GitDiffCardHeader-6LP_7oWh.js.gz +0 -0
- package/app/dist/assets/{InlineMessageEditorFrame-Dud8h1It.js → InlineMessageEditorFrame-DyVCSKBJ.js} +1 -1
- package/app/dist/assets/InlineMessageEditorFrame-DyVCSKBJ.js.br +0 -0
- package/app/dist/assets/InlineMessageEditorFrame-DyVCSKBJ.js.gz +0 -0
- package/app/dist/assets/{MachineRenameDialog-C_ZV5gEB.js → MachineRenameDialog-HGiXO0UG.js} +1 -1
- package/app/dist/assets/MachineRenameDialog-HGiXO0UG.js.br +0 -0
- package/app/dist/assets/MachineRenameDialog-HGiXO0UG.js.gz +0 -0
- package/app/dist/assets/{MachineSettingsView-BWSIpenw.js → MachineSettingsView-C4q9cbRr.js} +1 -1
- package/app/dist/assets/MachineSettingsView-C4q9cbRr.js.br +0 -0
- package/app/dist/assets/MachineSettingsView-C4q9cbRr.js.gz +0 -0
- package/app/dist/assets/{MicrophonePreferences-CNEhQgAS.js → MicrophonePreferences-qaOpiph1.js} +1 -1
- package/app/dist/assets/MicrophonePreferences-qaOpiph1.js.br +0 -0
- package/app/dist/assets/MicrophonePreferences-qaOpiph1.js.gz +0 -0
- package/app/dist/assets/{ModelReasoningMenu-BeNCpeQf.js → ModelReasoningMenu-CVmIvyBC.js} +1 -1
- package/app/dist/assets/ModelReasoningMenu-CVmIvyBC.js.br +0 -0
- package/app/dist/assets/ModelReasoningMenu-CVmIvyBC.js.gz +0 -0
- package/app/dist/assets/{NewTabPage-CsPDV6iC.js → NewTabPage-BD3LFok4.js} +1 -1
- package/app/dist/assets/NewTabPage-BD3LFok4.js.br +0 -0
- package/app/dist/assets/NewTabPage-BD3LFok4.js.gz +0 -0
- package/app/dist/assets/{NewThreadComposer-BY0jUSbs.js → NewThreadComposer-C2ZKRVh2.js} +1 -1
- package/app/dist/assets/NewThreadComposer-C2ZKRVh2.js.br +0 -0
- package/app/dist/assets/NewThreadComposer-C2ZKRVh2.js.gz +0 -0
- package/app/dist/assets/{OnboardingFlow-BQdrTtHC.js → OnboardingFlow-D7-YF2ZM.js} +1 -1
- package/app/dist/assets/OnboardingFlow-D7-YF2ZM.js.br +0 -0
- package/app/dist/assets/OnboardingFlow-D7-YF2ZM.js.gz +0 -0
- package/app/dist/assets/{OptionPicker-sql35hd_.js → OptionPicker-DzY4ri8R.js} +1 -1
- package/app/dist/assets/OptionPicker-DzY4ri8R.js.br +0 -0
- package/app/dist/assets/OptionPicker-DzY4ri8R.js.gz +0 -0
- package/app/dist/assets/{PaletteShell-B9KeWKsT.js → PaletteShell-4enjLs-M.js} +1 -1
- package/app/dist/assets/PaletteShell-4enjLs-M.js.br +0 -0
- package/app/dist/assets/PaletteShell-4enjLs-M.js.gz +0 -0
- package/app/dist/assets/{PaneMaximizeButton-CGBzyikf.js → PaneMaximizeButton-40ZGXf3w.js} +1 -1
- package/app/dist/assets/PaneMaximizeButton-40ZGXf3w.js.br +0 -0
- package/app/dist/assets/PaneMaximizeButton-40ZGXf3w.js.gz +0 -0
- package/app/dist/assets/{PierreLineSelectionActions-BYL6I0xE.js → PierreLineSelectionActions-DrQj-N__.js} +1 -1
- package/app/dist/assets/PierreLineSelectionActions-DrQj-N__.js.br +0 -0
- package/app/dist/assets/PierreLineSelectionActions-DrQj-N__.js.gz +0 -0
- package/app/dist/assets/{PluginPanelRightPanelHost-Dj-wS_Ki.js → PluginPanelRightPanelHost-Ha0PrCa9.js} +1 -1
- package/app/dist/assets/PluginPanelRightPanelHost-Ha0PrCa9.js.br +0 -0
- package/app/dist/assets/PluginPanelRightPanelHost-Ha0PrCa9.js.gz +0 -0
- package/app/dist/assets/{PluginThreadChat-Dh-No9s-.js → PluginThreadChat-D_tbXHEo.js} +1 -1
- package/app/dist/assets/PluginThreadChat-D_tbXHEo.js.br +0 -0
- package/app/dist/assets/PluginThreadChat-D_tbXHEo.js.gz +0 -0
- package/app/dist/assets/ProjectDetailSettingsView-Ckp-m-c0.js +1 -0
- package/app/dist/assets/ProjectDetailSettingsView-Ckp-m-c0.js.br +0 -0
- package/app/dist/assets/ProjectDetailSettingsView-Ckp-m-c0.js.gz +0 -0
- package/app/dist/assets/{ProjectMachineSetupDialog-BW4gUYj0.js → ProjectMachineSetupDialog-Bn43xkw-.js} +1 -1
- package/app/dist/assets/ProjectMachineSetupDialog-Bn43xkw-.js.br +0 -0
- package/app/dist/assets/ProjectMachineSetupDialog-Bn43xkw-.js.gz +0 -0
- package/app/dist/assets/{ProjectsSettingsSection-BI_xhcA2.js → ProjectsSettingsSection-DXHostGl.js} +1 -1
- package/app/dist/assets/ProjectsSettingsSection-DXHostGl.js.br +0 -0
- package/app/dist/assets/ProjectsSettingsSection-DXHostGl.js.gz +0 -0
- package/app/dist/assets/{QueuedMessagesList-BEyivVSE.js → QueuedMessagesList-C53i8_rz.js} +1 -1
- package/app/dist/assets/QueuedMessagesList-C53i8_rz.js.br +0 -0
- package/app/dist/assets/QueuedMessagesList-C53i8_rz.js.gz +0 -0
- package/app/dist/assets/{RemotePathBrowser-DVW5AwBs.js → RemotePathBrowser-CsCxZdUk.js} +1 -1
- package/app/dist/assets/RemotePathBrowser-CsCxZdUk.js.br +0 -0
- package/app/dist/assets/RemotePathBrowser-CsCxZdUk.js.gz +0 -0
- package/app/dist/assets/{RootComposeView-Cbnwq7j_.js → RootComposeView-CsV3Ut7E.js} +1 -1
- package/app/dist/assets/RootComposeView-CsV3Ut7E.js.br +0 -0
- package/app/dist/assets/RootComposeView-CsV3Ut7E.js.gz +0 -0
- package/app/dist/assets/{SecondaryPanelLayout-fG8BuYv-.js → SecondaryPanelLayout-BPTIpQ2F.js} +1 -1
- package/app/dist/assets/SecondaryPanelLayout-BPTIpQ2F.js.br +0 -0
- package/app/dist/assets/SecondaryPanelLayout-BPTIpQ2F.js.gz +0 -0
- package/app/dist/assets/{ServerMoveOverlayView-CPWZimVv.js → ServerMoveOverlayView-DxwZdF-Z.js} +1 -1
- package/app/dist/assets/ServerMoveOverlayView-DxwZdF-Z.js.br +0 -0
- package/app/dist/assets/ServerMoveOverlayView-DxwZdF-Z.js.gz +0 -0
- package/app/dist/assets/{SettingsSidebar-DxfoXXKW.js → SettingsSidebar-CYEXglCo.js} +1 -1
- package/app/dist/assets/SettingsSidebar-CYEXglCo.js.br +0 -0
- package/app/dist/assets/SettingsSidebar-CYEXglCo.js.gz +0 -0
- package/app/dist/assets/{SettingsView-D_DkKpuv.js → SettingsView-B3HpJfUo.js} +1 -1
- package/app/dist/assets/SettingsView-B3HpJfUo.js.br +0 -0
- package/app/dist/assets/SettingsView-B3HpJfUo.js.gz +0 -0
- package/app/dist/assets/{SidebarFooterCustomize-VQoenr5y.js → SidebarFooterCustomize-BGXeu0og.js} +1 -1
- package/app/dist/assets/SidebarFooterCustomize-BGXeu0og.js.br +0 -0
- package/app/dist/assets/SidebarFooterCustomize-BGXeu0og.js.gz +0 -0
- package/app/dist/assets/{SidebarVisibilityCustomize-DUKnlz9Y.js → SidebarVisibilityCustomize-Qy7hHO5j.js} +1 -1
- package/app/dist/assets/SidebarVisibilityCustomize-Qy7hHO5j.js.br +0 -0
- package/app/dist/assets/SidebarVisibilityCustomize-Qy7hHO5j.js.gz +0 -0
- package/app/dist/assets/{SourceCodeHost-BlXLvWv2.js → SourceCodeHost-CJpVOgCd.js} +2 -2
- package/app/dist/assets/SourceCodeHost-CJpVOgCd.js.br +0 -0
- package/app/dist/assets/SourceCodeHost-CJpVOgCd.js.gz +0 -0
- package/app/dist/assets/{SplitWorkspaceRoute-6w4G23kc.js → SplitWorkspaceRoute-CWPCkdjo.js} +2 -2
- package/app/dist/assets/SplitWorkspaceRoute-CWPCkdjo.js.br +0 -0
- package/app/dist/assets/SplitWorkspaceRoute-CWPCkdjo.js.gz +0 -0
- package/app/dist/assets/{TerminalOutputBlock-BxBSWJr_.js → TerminalOutputBlock-BzxpJ5H3.js} +1 -1
- package/app/dist/assets/TerminalOutputBlock-BzxpJ5H3.js.br +0 -0
- package/app/dist/assets/TerminalOutputBlock-BzxpJ5H3.js.gz +0 -0
- package/app/dist/assets/{ThreadActionsMenu-ChpSKv80.js → ThreadActionsMenu-DfUIyx3e.js} +1 -1
- package/app/dist/assets/ThreadActionsMenu-DfUIyx3e.js.br +0 -0
- package/app/dist/assets/ThreadActionsMenu-DfUIyx3e.js.gz +0 -0
- package/app/dist/assets/{ThreadDetailView-CfH3uWo-.js → ThreadDetailView-BqzwklQd.js} +3 -3
- package/app/dist/assets/ThreadDetailView-BqzwklQd.js.br +0 -0
- package/app/dist/assets/ThreadDetailView-BqzwklQd.js.gz +0 -0
- package/app/dist/assets/{ThreadSearchPaletteMode-B72v3f5V.js → ThreadSearchPaletteMode-Dni8lJt2.js} +1 -1
- package/app/dist/assets/ThreadSearchPaletteMode-Dni8lJt2.js.br +0 -0
- package/app/dist/assets/ThreadSearchPaletteMode-Dni8lJt2.js.gz +0 -0
- package/app/dist/assets/{ThreadSecondaryPanel-4nIZy4h9.js → ThreadSecondaryPanel-Cfah9-yR.js} +1 -1
- package/app/dist/assets/ThreadSecondaryPanel-Cfah9-yR.js.br +0 -0
- package/app/dist/assets/ThreadSecondaryPanel-Cfah9-yR.js.gz +0 -0
- package/app/dist/assets/{ThreadSecondaryPanelTabContent-8-e35_Me.js → ThreadSecondaryPanelTabContent-ByMkWr4B.js} +1 -1
- package/app/dist/assets/ThreadSecondaryPanelTabContent-ByMkWr4B.js.br +0 -0
- package/app/dist/assets/ThreadSecondaryPanelTabContent-ByMkWr4B.js.gz +0 -0
- package/app/dist/assets/{ThreadStatusGlyph-C9tzRtlV.js → ThreadStatusGlyph-MjAgpNtv.js} +1 -1
- package/app/dist/assets/ThreadStatusGlyph-MjAgpNtv.js.br +0 -0
- package/app/dist/assets/ThreadStatusGlyph-MjAgpNtv.js.gz +0 -0
- package/app/dist/assets/{ThreadTerminalPanel-CqTk9L2y.js → ThreadTerminalPanel-2UtGqd1Z.js} +1 -1
- package/app/dist/assets/ThreadTerminalPanel-2UtGqd1Z.js.br +0 -0
- package/app/dist/assets/ThreadTerminalPanel-2UtGqd1Z.js.gz +0 -0
- package/app/dist/assets/{ThreadTerminalView-B6XNBrJ9.js → ThreadTerminalView-BqsCrU1_.js} +1 -1
- package/app/dist/assets/ThreadTerminalView-BqsCrU1_.js.br +0 -0
- package/app/dist/assets/ThreadTerminalView-BqsCrU1_.js.gz +0 -0
- package/app/dist/assets/{ThreadTimelineNavigationContext-DbZHHZfY.js → ThreadTimelineNavigationContext-B_vg4bPl.js} +2 -2
- package/app/dist/assets/ThreadTimelineNavigationContext-B_vg4bPl.js.br +0 -0
- package/app/dist/assets/ThreadTimelineNavigationContext-B_vg4bPl.js.gz +0 -0
- package/app/dist/assets/{ThreadUnarchiveButton-CtjS9UkR.js → ThreadUnarchiveButton-CnlHu7Dv.js} +1 -1
- package/app/dist/assets/{TimelineDetailScroll-CpFZhWhU.js → TimelineDetailScroll-CIXDGLcx.js} +1 -1
- package/app/dist/assets/TimelineDetailScroll-CIXDGLcx.js.br +0 -0
- package/app/dist/assets/TimelineDetailScroll-CIXDGLcx.js.gz +0 -0
- package/app/dist/assets/{TimelineFileDiffBlock-JiOlR3O8.js → TimelineFileDiffBlock-Cy_6X6XY.js} +1 -1
- package/app/dist/assets/TimelineFileDiffBlock-Cy_6X6XY.js.br +0 -0
- package/app/dist/assets/TimelineFileDiffBlock-Cy_6X6XY.js.gz +0 -0
- package/app/dist/assets/{TimelineSelectionMenu-DT4qwoFI.js → TimelineSelectionMenu-DzrSCC7e.js} +1 -1
- package/app/dist/assets/TimelineSelectionMenu-DzrSCC7e.js.br +0 -0
- package/app/dist/assets/TimelineSelectionMenu-DzrSCC7e.js.gz +0 -0
- package/app/dist/assets/{ToolsView-nAAic88Z.js → ToolsView-B8oDS6Ek.js} +1 -1
- package/app/dist/assets/ToolsView-B8oDS6Ek.js.br +0 -0
- package/app/dist/assets/ToolsView-B8oDS6Ek.js.gz +0 -0
- package/app/dist/assets/{ToolsViewSplits-Blo3GJMQ.js → ToolsViewSplits-JK-JmYIg.js} +2 -2
- package/app/dist/assets/ToolsViewSplits-JK-JmYIg.js.br +0 -0
- package/app/dist/assets/ToolsViewSplits-JK-JmYIg.js.gz +0 -0
- package/app/dist/assets/{WaveformVisualizer-BrH_nwc4.js → WaveformVisualizer-GDJ4mJRx.js} +1 -1
- package/app/dist/assets/WaveformVisualizer-GDJ4mJRx.js.br +0 -0
- package/app/dist/assets/WaveformVisualizer-GDJ4mJRx.js.gz +0 -0
- package/app/dist/assets/{absolute-file-path-W_eh4kPq.js → absolute-file-path-B-cUOroV.js} +1 -1
- package/app/dist/assets/{app-fixed-tab-navigation-DX9s-gCj.js → app-fixed-tab-navigation-BpDuGNDS.js} +1 -1
- package/app/dist/assets/app-fixed-tab-navigation-BpDuGNDS.js.br +0 -0
- package/app/dist/assets/app-fixed-tab-navigation-BpDuGNDS.js.gz +0 -0
- package/app/dist/assets/{audio-input-device-preference-DsU6GGNE.js → audio-input-device-preference-BeKjzmnK.js} +1 -1
- package/app/dist/assets/audio-input-device-preference-BeKjzmnK.js.br +0 -0
- package/app/dist/assets/audio-input-device-preference-BeKjzmnK.js.gz +0 -0
- package/app/dist/assets/{bottom-anchored-scroll-body-C8n22V_o.js → bottom-anchored-scroll-body-DaHi9M7W.js} +1 -1
- package/app/dist/assets/bottom-anchored-scroll-body-DaHi9M7W.js.br +0 -0
- package/app/dist/assets/bottom-anchored-scroll-body-DaHi9M7W.js.gz +0 -0
- package/app/dist/assets/{browser-url-B0SjaYti.js → browser-url-BdtGkCbj.js} +1 -1
- package/app/dist/assets/browser-url-BdtGkCbj.js.br +0 -0
- package/app/dist/assets/browser-url-BdtGkCbj.js.gz +0 -0
- package/app/dist/assets/{checkbox-Ct38DhHB.js → checkbox-5zZ_V1_F.js} +1 -1
- package/app/dist/assets/checkbox-5zZ_V1_F.js.br +0 -0
- package/app/dist/assets/checkbox-5zZ_V1_F.js.gz +0 -0
- package/app/dist/assets/{code-loading-skeletons-C_099GEq.js → code-loading-skeletons-DzoCzgll.js} +1 -1
- package/app/dist/assets/code-loading-skeletons-DzoCzgll.js.br +0 -0
- package/app/dist/assets/code-loading-skeletons-DzoCzgll.js.gz +0 -0
- package/app/dist/assets/{code-rendering-OxBy5zPr.js → code-rendering-A15j47Uy.js} +1 -1
- package/app/dist/assets/{code-theme-registration-BokyXo30.js → code-theme-registration-q5iRcekZ.js} +1 -1
- package/app/dist/assets/{detail-card-Cj628JNK.js → detail-card-BvFcq0Ru.js} +1 -1
- package/app/dist/assets/detail-card-BvFcq0Ru.js.br +0 -0
- package/app/dist/assets/detail-card-BvFcq0Ru.js.gz +0 -0
- package/app/dist/assets/{diff-stats-tally-MtORWItG.js → diff-stats-tally-DA41wrwM.js} +1 -1
- package/app/dist/assets/diff-stats-tally-DA41wrwM.js.br +0 -0
- package/app/dist/assets/diff-stats-tally-DA41wrwM.js.gz +0 -0
- package/app/dist/assets/{environment-mutations-rP4eROm2.js → environment-mutations-Bl2PK8kR.js} +1 -1
- package/app/dist/assets/environment-mutations-Bl2PK8kR.js.br +0 -0
- package/app/dist/assets/environment-mutations-Bl2PK8kR.js.gz +0 -0
- package/app/dist/assets/{environment-workspace-display-O1JRHfbV.js → environment-workspace-display-DdMsNL4x.js} +3 -3
- package/app/dist/assets/environment-workspace-display-DdMsNL4x.js.br +0 -0
- package/app/dist/assets/environment-workspace-display-DdMsNL4x.js.gz +0 -0
- package/app/dist/assets/{event-code-block-DqUZCAii.js → event-code-block-DT4pyQ5R.js} +1 -1
- package/app/dist/assets/event-code-block-DT4pyQ5R.js.br +0 -0
- package/app/dist/assets/event-code-block-DT4pyQ5R.js.gz +0 -0
- package/app/dist/assets/{expandable-text-herJC70e.js → expandable-text-CtGFLpBX.js} +1 -1
- package/app/dist/assets/expandable-text-CtGFLpBX.js.br +0 -0
- package/app/dist/assets/expandable-text-CtGFLpBX.js.gz +0 -0
- package/app/dist/assets/{file-opener-preference-BEeek6dm.js → file-opener-preference-B5sOAhVM.js} +1 -1
- package/app/dist/assets/{file-path-link-Cni9Azi2.js → file-path-link-xsn9GiAq.js} +1 -1
- package/app/dist/assets/file-path-link-xsn9GiAq.js.br +0 -0
- package/app/dist/assets/file-path-link-xsn9GiAq.js.gz +0 -0
- package/app/dist/assets/{host-mutations-Ckc-eVys.js → host-mutations-Bf4idS3m.js} +1 -1
- package/app/dist/assets/host-mutations-Bf4idS3m.js.br +0 -0
- package/app/dist/assets/host-mutations-Bf4idS3m.js.gz +0 -0
- package/app/dist/assets/{icon-extended-DDFkslJU.js → icon-extended-C7x9E4W9.js} +1 -1
- package/app/dist/assets/icon-extended-C7x9E4W9.js.br +0 -0
- package/app/dist/assets/icon-extended-C7x9E4W9.js.gz +0 -0
- package/app/dist/assets/{image-lightbox-BW1bqQJM.js → image-lightbox-CzY6y14n.js} +1 -1
- package/app/dist/assets/image-lightbox-CzY6y14n.js.br +0 -0
- package/app/dist/assets/image-lightbox-CzY6y14n.js.gz +0 -0
- package/app/dist/assets/index-B-RDC4LU.js +395 -0
- package/app/dist/assets/index-B-RDC4LU.js.br +0 -0
- package/app/dist/assets/index-B-RDC4LU.js.gz +0 -0
- package/app/dist/assets/{inline-rename-editor-wjwfk7v2.js → inline-rename-editor-DUVacR_R.js} +1 -1
- package/app/dist/assets/inline-rename-editor-DUVacR_R.js.br +0 -0
- package/app/dist/assets/inline-rename-editor-DUVacR_R.js.gz +0 -0
- package/app/dist/assets/{launcherRow-rIW7Z6Xm.js → launcherRow-C9Htfook.js} +1 -1
- package/app/dist/assets/launcherRow-C9Htfook.js.br +0 -0
- package/app/dist/assets/launcherRow-C9Htfook.js.gz +0 -0
- package/app/dist/assets/{localhost-link-rewrite-description-Bovg3W--.js → localhost-link-rewrite-description-DfPXtfPs.js} +1 -1
- package/app/dist/assets/localhost-link-rewrite-description-DfPXtfPs.js.br +0 -0
- package/app/dist/assets/localhost-link-rewrite-description-DfPXtfPs.js.gz +0 -0
- package/app/dist/assets/{machine-provider-queries-CRlWTEz7.js → machine-provider-queries-By9Ipha4.js} +1 -1
- package/app/dist/assets/machine-provider-queries-By9Ipha4.js.br +0 -0
- package/app/dist/assets/machine-provider-queries-By9Ipha4.js.gz +0 -0
- package/app/dist/assets/{machine-server-access-D3hixOIC.js → machine-server-access-6584jQ7-.js} +1 -1
- package/app/dist/assets/{markdown-file-image-routing-DAIVjxLg.js → markdown-file-image-routing-0_tf5d6g.js} +1 -1
- package/app/dist/assets/{markdown-html-B-Kyh3zI.js → markdown-html-JK4Gnuli.js} +1 -1
- package/app/dist/assets/markdown-html-JK4Gnuli.js.br +0 -0
- package/app/dist/assets/markdown-html-JK4Gnuli.js.gz +0 -0
- package/app/dist/assets/{markdown-local-file-link-C89PR8d5.js → markdown-local-file-link-DXjnoCIE.js} +1 -1
- package/app/dist/assets/markdown-local-file-link-DXjnoCIE.js.br +0 -0
- package/app/dist/assets/markdown-local-file-link-DXjnoCIE.js.gz +0 -0
- package/app/dist/assets/{markdown-preview-B7BmqIlu.js → markdown-preview-Bfwf40CC.js} +2 -2
- package/app/dist/assets/markdown-preview-Bfwf40CC.js.br +0 -0
- package/app/dist/assets/markdown-preview-Bfwf40CC.js.gz +0 -0
- package/app/dist/assets/{markdown-prompt-mentions-B0JRhgrI.js → markdown-prompt-mentions-BuHEkhJs.js} +1 -1
- package/app/dist/assets/markdown-prompt-mentions-BuHEkhJs.js.br +0 -0
- package/app/dist/assets/markdown-prompt-mentions-BuHEkhJs.js.gz +0 -0
- package/app/dist/assets/{model-load-error-message-B-HKqgUD.js → model-load-error-message-CnA6byT0.js} +1 -1
- package/app/dist/assets/model-load-error-message-CnA6byT0.js.br +0 -0
- package/app/dist/assets/model-load-error-message-CnA6byT0.js.gz +0 -0
- package/app/dist/assets/onboarding-telemetry-D6SXoh98.js +1 -0
- package/app/dist/assets/{open-in-editor-button-CQGreiCk.js → open-in-editor-button-jScMiuob.js} +1 -1
- package/app/dist/assets/open-in-editor-button-jScMiuob.js.br +0 -0
- package/app/dist/assets/open-in-editor-button-jScMiuob.js.gz +0 -0
- package/app/dist/assets/{page-shell-BHTOdeQn.js → page-shell-ClYdhKtX.js} +1 -1
- package/app/dist/assets/page-shell-ClYdhKtX.js.br +0 -0
- package/app/dist/assets/page-shell-ClYdhKtX.js.gz +0 -0
- package/app/dist/assets/{pierre-worker-pool-Bm9cLA-c.js → pierre-worker-pool-D1nZ9Lcz.js} +1 -1
- package/app/dist/assets/pierre-worker-pool-D1nZ9Lcz.js.br +0 -0
- package/app/dist/assets/pierre-worker-pool-D1nZ9Lcz.js.gz +0 -0
- package/app/dist/assets/{plugin-detail-navigation-CmSGTNyL.js → plugin-detail-navigation-BD4jDXuP.js} +1 -1
- package/app/dist/assets/plugin-detail-navigation-BD4jDXuP.js.br +0 -0
- package/app/dist/assets/plugin-detail-navigation-BD4jDXuP.js.gz +0 -0
- package/app/dist/assets/{plugin-frontend-BdQdYbWd.js → plugin-frontend-qfGFykt-.js} +3 -3
- package/app/dist/assets/plugin-frontend-qfGFykt-.js.br +0 -0
- package/app/dist/assets/plugin-frontend-qfGFykt-.js.gz +0 -0
- package/app/dist/assets/{plugin-ui-DyNDyPD9.js → plugin-ui-DfbeKd73.js} +1 -1
- package/app/dist/assets/plugin-ui-DfbeKd73.js.br +0 -0
- package/app/dist/assets/plugin-ui-DfbeKd73.js.gz +0 -0
- package/app/dist/assets/{project-default-execution-options-query-h6eTG6_Q.js → project-default-execution-options-query-DQKDDkRo.js} +1 -1
- package/app/dist/assets/{queued-editor-typeahead-layout-BKui5z7C.js → queued-editor-typeahead-layout-DKGYsvQ-.js} +1 -1
- package/app/dist/assets/queued-editor-typeahead-layout-DKGYsvQ-.js.br +0 -0
- package/app/dist/assets/queued-editor-typeahead-layout-DKGYsvQ-.js.gz +0 -0
- package/app/dist/assets/{queued-messages-layout-BuEilXwP.js → queued-messages-layout-ClZkWHAV.js} +1 -1
- package/app/dist/assets/queued-messages-layout-ClZkWHAV.js.br +0 -0
- package/app/dist/assets/queued-messages-layout-ClZkWHAV.js.gz +0 -0
- package/app/dist/assets/{resource-list-B6MkAu8v.js → resource-list-CC7zN47b.js} +1 -1
- package/app/dist/assets/resource-list-CC7zN47b.js.br +0 -0
- package/app/dist/assets/resource-list-CC7zN47b.js.gz +0 -0
- package/app/dist/assets/root-compose-create-preference-z0-Xe1ss.js +1 -0
- package/app/dist/assets/{save-file-DYAtq7A9.js → save-file-Cs9LWQ4E.js} +1 -1
- package/app/dist/assets/{settings-nav-DbICcozy.js → settings-nav-BKMVpc5b.js} +1 -1
- package/app/dist/assets/settings-nav-BKMVpc5b.js.br +0 -0
- package/app/dist/assets/settings-nav-BKMVpc5b.js.gz +0 -0
- package/app/dist/assets/{settings-sections-Cq0VX9E8.js → settings-sections-LqqPm8q3.js} +1 -1
- package/app/dist/assets/settings-sections-LqqPm8q3.js.br +0 -0
- package/app/dist/assets/settings-sections-LqqPm8q3.js.gz +0 -0
- package/app/dist/assets/{shortcut-pill-DldxrKgx.js → shortcut-pill-DOMeVrnR.js} +1 -1
- package/app/dist/assets/{sidebarTouchSensor-D7jKXrfM.js → sidebarTouchSensor-PP8-SQld.js} +1 -1
- package/app/dist/assets/sidebarTouchSensor-PP8-SQld.js.br +0 -0
- package/app/dist/assets/sidebarTouchSensor-PP8-SQld.js.gz +0 -0
- package/app/dist/assets/{switch-CzvlSesf.js → switch-B9nrFpZc.js} +1 -1
- package/app/dist/assets/switch-B9nrFpZc.js.br +0 -0
- package/app/dist/assets/switch-B9nrFpZc.js.gz +0 -0
- package/app/dist/assets/{textarea-9yaIMD7J.js → textarea-2fJEsqsi.js} +1 -1
- package/app/dist/assets/{thread-event-parser-BqVpKC6z.js → thread-event-parser-DedSEtmp.js} +1 -1
- package/app/dist/assets/thread-event-parser-DedSEtmp.js.br +0 -0
- package/app/dist/assets/thread-event-parser-DedSEtmp.js.gz +0 -0
- package/app/dist/assets/{thread-panel-queries-C3MI4mdc.js → thread-panel-queries-5N40syTx.js} +1 -1
- package/app/dist/assets/thread-panel-queries-5N40syTx.js.br +0 -0
- package/app/dist/assets/thread-panel-queries-5N40syTx.js.gz +0 -0
- package/app/dist/assets/{thread-runtime-mutations-Cr1H7KSz.js → thread-runtime-mutations-BY5xzme0.js} +1 -1
- package/app/dist/assets/thread-runtime-mutations-BY5xzme0.js.br +0 -0
- package/app/dist/assets/thread-runtime-mutations-BY5xzme0.js.gz +0 -0
- package/app/dist/assets/{thread-terminal-queries-B4JkOWS2.js → thread-terminal-queries-BF7AB7qh.js} +1 -1
- package/app/dist/assets/thread-terminal-queries-BF7AB7qh.js.br +0 -0
- package/app/dist/assets/thread-terminal-queries-BF7AB7qh.js.gz +0 -0
- package/app/dist/assets/{threadRecentItems-DI2mgj7S.js → threadRecentItems-CYYbbS1r.js} +1 -1
- package/app/dist/assets/threadRecentItems-CYYbbS1r.js.br +0 -0
- package/app/dist/assets/threadRecentItems-CYYbbS1r.js.gz +0 -0
- package/app/dist/assets/{threadWorkspaceOpenPath-BQgtUYL5.js → threadWorkspaceOpenPath-B5anoH2-.js} +1 -1
- package/app/dist/assets/threadWorkspaceOpenPath-B5anoH2-.js.br +0 -0
- package/app/dist/assets/threadWorkspaceOpenPath-B5anoH2-.js.gz +0 -0
- package/app/dist/assets/{title-bar-scroll-fade-CxbgbTcm.js → title-bar-scroll-fade-BfqL4WEJ.js} +1 -1
- package/app/dist/assets/title-bar-scroll-fade-BfqL4WEJ.js.br +0 -0
- package/app/dist/assets/title-bar-scroll-fade-BfqL4WEJ.js.gz +0 -0
- package/app/dist/assets/{truncate-start-CaCnKnh9.js → truncate-start-D-P3rLti.js} +1 -1
- package/app/dist/assets/{use-hover-popover-CyIdak3c.js → use-hover-popover-Bb8PuVyu.js} +1 -1
- package/app/dist/assets/use-hover-popover-Bb8PuVyu.js.br +0 -0
- package/app/dist/assets/use-hover-popover-Bb8PuVyu.js.gz +0 -0
- package/app/dist/assets/{useElementWidth-CL3Nb-eq.js → useElementWidth-vSwGqg9a.js} +1 -1
- package/app/dist/assets/useElementWidth-vSwGqg9a.js.br +0 -0
- package/app/dist/assets/useElementWidth-vSwGqg9a.js.gz +0 -0
- package/app/dist/assets/{useLocalOpenTargets-yzd9-Ceh.js → useLocalOpenTargets-DqjYzi0b.js} +1 -1
- package/app/dist/assets/useLocalOpenTargets-DqjYzi0b.js.br +0 -0
- package/app/dist/assets/useLocalOpenTargets-DqjYzi0b.js.gz +0 -0
- package/app/dist/assets/{usePanelResizeSnap-dys9IwEk.js → usePanelResizeSnap-Dvi7sa3e.js} +1 -1
- package/app/dist/assets/usePanelResizeSnap-Dvi7sa3e.js.br +0 -0
- package/app/dist/assets/usePanelResizeSnap-Dvi7sa3e.js.gz +0 -0
- package/app/dist/assets/{usePanelTerminals-BN8UCJFO.js → usePanelTerminals-B9MNSur4.js} +1 -1
- package/app/dist/assets/usePanelTerminals-B9MNSur4.js.br +0 -0
- package/app/dist/assets/usePanelTerminals-B9MNSur4.js.gz +0 -0
- package/app/dist/assets/{usePathSuggestions-DkeFAE7l.js → usePathSuggestions-zhZ-4fh8.js} +1 -1
- package/app/dist/assets/usePathSuggestions-zhZ-4fh8.js.br +0 -0
- package/app/dist/assets/usePathSuggestions-zhZ-4fh8.js.gz +0 -0
- package/app/dist/assets/{useResolvedLiveFileTarget-43fAKgDx.js → useResolvedLiveFileTarget-CZZwqw4L.js} +1 -1
- package/app/dist/assets/useResolvedLiveFileTarget-CZZwqw4L.js.br +0 -0
- package/app/dist/assets/useResolvedLiveFileTarget-CZZwqw4L.js.gz +0 -0
- package/app/dist/assets/{useThreadTerminalController-DcWLbe8W.js → useThreadTerminalController-CvXy-5HP.js} +1 -1
- package/app/dist/assets/useThreadTerminalController-CvXy-5HP.js.br +0 -0
- package/app/dist/assets/useThreadTerminalController-CvXy-5HP.js.gz +0 -0
- package/app/dist/assets/{workspace-change-summary-Bd3p-LXz.js → workspace-change-summary-CY01JLmJ.js} +1 -1
- package/app/dist/assets/workspace-change-summary-CY01JLmJ.js.br +0 -0
- package/app/dist/assets/workspace-change-summary-CY01JLmJ.js.gz +0 -0
- package/app/dist/assets/{workspace-checkout-display-DMp28yCr.js → workspace-checkout-display-C9B0QPLi.js} +4 -4
- package/app/dist/assets/workspace-checkout-display-C9B0QPLi.js.br +0 -0
- package/app/dist/assets/workspace-checkout-display-C9B0QPLi.js.gz +0 -0
- package/app/dist/index.html +17 -17
- package/app/dist/index.html.br +0 -0
- package/app/dist/index.html.gz +0 -0
- package/dist/index.d.ts +35 -6
- package/dist/index.js +9 -5
- package/host-daemon/dist/bb +2 -2
- package/host-daemon/dist/bb-chunks/{browser-DVIVPPSL.js → browser-3RYUCU4H.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-ATDR5E2C.js → chunk-CZ4K4Z4T.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-ZWBRH7R6.js → chunk-DCRUVPRR.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-7EOZF4HA.js → chunk-F7XCHQA3.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-JWA6VJYL.js → chunk-FYCUA6H6.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-5ZMA4MIX.js → chunk-FZ76WJJG.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-UXSJP3YM.js → chunk-GVXLVAX4.js} +1 -1
- package/host-daemon/dist/bb-chunks/chunk-HDUE2YKX.js +2199 -0
- package/host-daemon/dist/bb-chunks/{chunk-REEBSQ75.js → chunk-L5UJ4QUD.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-QE47NRKX.js → chunk-NZY63D4X.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-MLYXPSJC.js → chunk-UCNQXYXP.js} +1 -1
- package/host-daemon/dist/bb-chunks/chunk-WMCZMPZ4.js +2 -0
- package/host-daemon/dist/bb-chunks/{client-YJBBA4JS.js → client-NLWJKXJ2.js} +1 -1
- package/host-daemon/dist/bb-chunks/{commander-errors-P6LP2OHL.js → commander-errors-GDOJDU37.js} +1 -1
- package/host-daemon/dist/bb-chunks/{context-env-LJ5IITUO.js → context-env-VLEFLYWD.js} +1 -1
- package/host-daemon/dist/bb-chunks/{context-hints-MUUUMT2P.js → context-hints-FXEXGMFT.js} +1 -1
- package/host-daemon/dist/bb-chunks/{diagnostics-5EMHJNW7.js → diagnostics-ZKJGPJUH.js} +1 -1
- package/host-daemon/dist/bb-chunks/{environment-ZRSQFVHG.js → environment-CY5JUFSR.js} +1 -1
- package/host-daemon/dist/bb-chunks/{file-AEVJYJAY.js → file-KGZLZ36T.js} +1 -1
- package/host-daemon/dist/bb-chunks/{guide-GLY5UY4M.js → guide-MXAVSGKZ.js} +1 -1
- package/host-daemon/dist/bb-chunks/{machine-Z5QSPWEE.js → machine-Y7XFS7EJ.js} +1 -1
- package/host-daemon/dist/bb-chunks/{marketplace-4CGZ3NTM.js → marketplace-QLPRDZTC.js} +1 -1
- package/host-daemon/dist/bb-chunks/{plugin-VO7RP4JU.js → plugin-K276UYTK.js} +1 -1
- package/host-daemon/dist/bb-chunks/{plugin-cli-proxy-6Y6TTP7A.js → plugin-cli-proxy-QE7C6YLF.js} +1 -1
- package/host-daemon/dist/bb-chunks/project-QD44GO6S.js +2 -0
- package/host-daemon/dist/bb-chunks/{prompt-history-ZNIBNYER.js → prompt-history-YGK557NG.js} +1 -1
- package/host-daemon/dist/bb-chunks/{provider-TJ4DGKBX.js → provider-FAAY2EKV.js} +1 -1
- package/host-daemon/dist/bb-chunks/{server-YMSYCILC.js → server-Y7FRWA4U.js} +1 -1
- package/host-daemon/dist/bb-chunks/{settings-5CKNFTFZ.js → settings-76RZ35GN.js} +1 -1
- package/host-daemon/dist/bb-chunks/{skill-BMQPIFAD.js → skill-HMSLPSPW.js} +1 -1
- package/host-daemon/dist/bb-chunks/{status-2DJ3O6QU.js → status-GJFZ5YDD.js} +1 -1
- package/host-daemon/dist/bb-chunks/{terminal-NWC5PO4A.js → terminal-LSZHPIET.js} +1 -1
- package/host-daemon/dist/bb-chunks/{theme-OEOGYFXJ.js → theme-BMV5THCU.js} +1 -1
- package/host-daemon/dist/bb-chunks/{thread-AI6SXNXK.js → thread-UZ44ZBA2.js} +1 -1
- package/host-daemon/dist/bb-chunks/thread-event-parser-SIFYMDOV.js +2 -0
- package/host-daemon/dist/bb-chunks/{updates-DFLJJDO4.js → updates-IDCLXRIV.js} +1 -1
- package/host-daemon/dist/bb-chunks/{voice-ZSACREC3.js → voice-EXZARJ2J.js} +1 -1
- package/host-daemon/dist/daemon-bundle.mjs +102 -102
- package/package.json +1 -1
- package/server/dist/builtin-plugins/orbit/dist/assets/orbit/revision +1 -1
- package/server/dist/builtin-plugins/orbit/dist/server.js +52 -52
- package/server/dist/drizzle/0147_project_permission_escalation.sql +1 -0
- package/server/dist/drizzle/meta/0147_snapshot.json +5295 -0
- package/server/dist/drizzle/meta/_journal.json +7 -0
- package/server/dist/start-server.js +26 -7
- package/app/dist/assets/AddMachineDialog-4BQFC118.js.br +0 -0
- package/app/dist/assets/AddMachineDialog-4BQFC118.js.gz +0 -0
- package/app/dist/assets/AppFileExternalNavigationDispatcher-fGD_vTns.js.br +0 -0
- package/app/dist/assets/AppFileExternalNavigationDispatcher-fGD_vTns.js.gz +0 -0
- package/app/dist/assets/BbDiff-BkqgAZD9.js.br +0 -0
- package/app/dist/assets/BbDiff-BkqgAZD9.js.gz +0 -0
- package/app/dist/assets/BbDiffSplit-DTvWaW-n.js.br +0 -0
- package/app/dist/assets/BbDiffSplit-DTvWaW-n.js.gz +0 -0
- package/app/dist/assets/BbSourceCode-Dqw4VrLu.js.br +0 -0
- package/app/dist/assets/BbSourceCode-Dqw4VrLu.js.gz +0 -0
- package/app/dist/assets/BrowserTabDeck-CuHEyZd6.js.br +0 -0
- package/app/dist/assets/BrowserTabDeck-CuHEyZd6.js.gz +0 -0
- package/app/dist/assets/CommandPaletteBody-DynxiDg6.js.br +0 -0
- package/app/dist/assets/CommandPaletteBody-DynxiDg6.js.gz +0 -0
- package/app/dist/assets/DiffHost-3UTZIJNs.js.br +0 -0
- package/app/dist/assets/DiffHost-3UTZIJNs.js.gz +0 -0
- package/app/dist/assets/ExperimentalFileLinkMenu-C0RXVabs.js.br +0 -0
- package/app/dist/assets/ExperimentalFileLinkMenu-C0RXVabs.js.gz +0 -0
- package/app/dist/assets/FilePreview-BxgJ2jjI.js.br +0 -0
- package/app/dist/assets/FilePreview-BxgJ2jjI.js.gz +0 -0
- package/app/dist/assets/GitDiffCardHeader-Ce736y-m.js.br +0 -0
- package/app/dist/assets/GitDiffCardHeader-Ce736y-m.js.gz +0 -0
- package/app/dist/assets/InlineMessageEditorFrame-Dud8h1It.js.br +0 -0
- package/app/dist/assets/InlineMessageEditorFrame-Dud8h1It.js.gz +0 -0
- package/app/dist/assets/MachineRenameDialog-C_ZV5gEB.js.br +0 -0
- package/app/dist/assets/MachineRenameDialog-C_ZV5gEB.js.gz +0 -0
- package/app/dist/assets/MachineSettingsView-BWSIpenw.js.br +0 -0
- package/app/dist/assets/MachineSettingsView-BWSIpenw.js.gz +0 -0
- package/app/dist/assets/MicrophonePreferences-CNEhQgAS.js.br +0 -0
- package/app/dist/assets/MicrophonePreferences-CNEhQgAS.js.gz +0 -0
- package/app/dist/assets/ModelReasoningMenu-BeNCpeQf.js.br +0 -0
- package/app/dist/assets/ModelReasoningMenu-BeNCpeQf.js.gz +0 -0
- package/app/dist/assets/NewTabPage-CsPDV6iC.js.br +0 -0
- package/app/dist/assets/NewTabPage-CsPDV6iC.js.gz +0 -0
- package/app/dist/assets/NewThreadComposer-BY0jUSbs.js.br +0 -0
- package/app/dist/assets/NewThreadComposer-BY0jUSbs.js.gz +0 -0
- package/app/dist/assets/OnboardingFlow-BQdrTtHC.js.br +0 -0
- package/app/dist/assets/OnboardingFlow-BQdrTtHC.js.gz +0 -0
- package/app/dist/assets/OptionPicker-sql35hd_.js.br +0 -0
- package/app/dist/assets/OptionPicker-sql35hd_.js.gz +0 -0
- package/app/dist/assets/PaletteShell-B9KeWKsT.js.br +0 -0
- package/app/dist/assets/PaletteShell-B9KeWKsT.js.gz +0 -0
- package/app/dist/assets/PaneMaximizeButton-CGBzyikf.js.br +0 -0
- package/app/dist/assets/PaneMaximizeButton-CGBzyikf.js.gz +0 -0
- package/app/dist/assets/PierreLineSelectionActions-BYL6I0xE.js.br +0 -0
- package/app/dist/assets/PierreLineSelectionActions-BYL6I0xE.js.gz +0 -0
- package/app/dist/assets/PluginPanelRightPanelHost-Dj-wS_Ki.js.br +0 -0
- package/app/dist/assets/PluginPanelRightPanelHost-Dj-wS_Ki.js.gz +0 -0
- package/app/dist/assets/PluginThreadChat-Dh-No9s-.js.br +0 -0
- package/app/dist/assets/PluginThreadChat-Dh-No9s-.js.gz +0 -0
- package/app/dist/assets/ProjectDetailSettingsView-BOV7URzQ.js +0 -1
- package/app/dist/assets/ProjectDetailSettingsView-BOV7URzQ.js.br +0 -0
- package/app/dist/assets/ProjectDetailSettingsView-BOV7URzQ.js.gz +0 -0
- package/app/dist/assets/ProjectMachineSetupDialog-BW4gUYj0.js.br +0 -0
- package/app/dist/assets/ProjectMachineSetupDialog-BW4gUYj0.js.gz +0 -0
- package/app/dist/assets/ProjectsSettingsSection-BI_xhcA2.js.br +0 -0
- package/app/dist/assets/ProjectsSettingsSection-BI_xhcA2.js.gz +0 -0
- package/app/dist/assets/QueuedMessagesList-BEyivVSE.js.br +0 -0
- package/app/dist/assets/QueuedMessagesList-BEyivVSE.js.gz +0 -0
- package/app/dist/assets/RemotePathBrowser-DVW5AwBs.js.br +0 -0
- package/app/dist/assets/RemotePathBrowser-DVW5AwBs.js.gz +0 -0
- package/app/dist/assets/RootComposeView-Cbnwq7j_.js.br +0 -0
- package/app/dist/assets/RootComposeView-Cbnwq7j_.js.gz +0 -0
- package/app/dist/assets/SecondaryPanelLayout-fG8BuYv-.js.br +0 -0
- package/app/dist/assets/SecondaryPanelLayout-fG8BuYv-.js.gz +0 -0
- package/app/dist/assets/ServerMoveOverlayView-CPWZimVv.js.br +0 -0
- package/app/dist/assets/ServerMoveOverlayView-CPWZimVv.js.gz +0 -0
- package/app/dist/assets/SettingsSidebar-DxfoXXKW.js.br +0 -0
- package/app/dist/assets/SettingsSidebar-DxfoXXKW.js.gz +0 -0
- package/app/dist/assets/SettingsView-D_DkKpuv.js.br +0 -0
- package/app/dist/assets/SettingsView-D_DkKpuv.js.gz +0 -0
- package/app/dist/assets/SidebarFooterCustomize-VQoenr5y.js.br +0 -0
- package/app/dist/assets/SidebarFooterCustomize-VQoenr5y.js.gz +0 -0
- package/app/dist/assets/SidebarVisibilityCustomize-DUKnlz9Y.js.br +0 -0
- package/app/dist/assets/SidebarVisibilityCustomize-DUKnlz9Y.js.gz +0 -0
- package/app/dist/assets/SourceCodeHost-BlXLvWv2.js.br +0 -0
- package/app/dist/assets/SourceCodeHost-BlXLvWv2.js.gz +0 -0
- package/app/dist/assets/SplitWorkspaceRoute-6w4G23kc.js.br +0 -0
- package/app/dist/assets/SplitWorkspaceRoute-6w4G23kc.js.gz +0 -0
- package/app/dist/assets/TerminalOutputBlock-BxBSWJr_.js.br +0 -0
- package/app/dist/assets/TerminalOutputBlock-BxBSWJr_.js.gz +0 -0
- package/app/dist/assets/ThreadActionsMenu-ChpSKv80.js.br +0 -0
- package/app/dist/assets/ThreadActionsMenu-ChpSKv80.js.gz +0 -0
- package/app/dist/assets/ThreadDetailView-CfH3uWo-.js.br +0 -0
- package/app/dist/assets/ThreadDetailView-CfH3uWo-.js.gz +0 -0
- package/app/dist/assets/ThreadSearchPaletteMode-B72v3f5V.js.br +0 -0
- package/app/dist/assets/ThreadSearchPaletteMode-B72v3f5V.js.gz +0 -0
- package/app/dist/assets/ThreadSecondaryPanel-4nIZy4h9.js.br +0 -0
- package/app/dist/assets/ThreadSecondaryPanel-4nIZy4h9.js.gz +0 -0
- package/app/dist/assets/ThreadSecondaryPanelTabContent-8-e35_Me.js.br +0 -0
- package/app/dist/assets/ThreadSecondaryPanelTabContent-8-e35_Me.js.gz +0 -0
- package/app/dist/assets/ThreadStatusGlyph-C9tzRtlV.js.br +0 -0
- package/app/dist/assets/ThreadStatusGlyph-C9tzRtlV.js.gz +0 -0
- package/app/dist/assets/ThreadTerminalPanel-CqTk9L2y.js.br +0 -0
- package/app/dist/assets/ThreadTerminalPanel-CqTk9L2y.js.gz +0 -0
- package/app/dist/assets/ThreadTerminalView-B6XNBrJ9.js.br +0 -0
- package/app/dist/assets/ThreadTerminalView-B6XNBrJ9.js.gz +0 -0
- package/app/dist/assets/ThreadTimelineNavigationContext-DbZHHZfY.js.br +0 -0
- package/app/dist/assets/ThreadTimelineNavigationContext-DbZHHZfY.js.gz +0 -0
- package/app/dist/assets/TimelineDetailScroll-CpFZhWhU.js.br +0 -0
- package/app/dist/assets/TimelineDetailScroll-CpFZhWhU.js.gz +0 -0
- package/app/dist/assets/TimelineFileDiffBlock-JiOlR3O8.js.br +0 -0
- package/app/dist/assets/TimelineFileDiffBlock-JiOlR3O8.js.gz +0 -0
- package/app/dist/assets/TimelineSelectionMenu-DT4qwoFI.js.br +0 -0
- package/app/dist/assets/TimelineSelectionMenu-DT4qwoFI.js.gz +0 -0
- package/app/dist/assets/ToolsView-nAAic88Z.js.br +0 -0
- package/app/dist/assets/ToolsView-nAAic88Z.js.gz +0 -0
- package/app/dist/assets/ToolsViewSplits-Blo3GJMQ.js.br +0 -0
- package/app/dist/assets/ToolsViewSplits-Blo3GJMQ.js.gz +0 -0
- package/app/dist/assets/WaveformVisualizer-BrH_nwc4.js.br +0 -0
- package/app/dist/assets/WaveformVisualizer-BrH_nwc4.js.gz +0 -0
- package/app/dist/assets/app-fixed-tab-navigation-DX9s-gCj.js.br +0 -0
- package/app/dist/assets/app-fixed-tab-navigation-DX9s-gCj.js.gz +0 -0
- package/app/dist/assets/audio-input-device-preference-DsU6GGNE.js.br +0 -0
- package/app/dist/assets/audio-input-device-preference-DsU6GGNE.js.gz +0 -0
- package/app/dist/assets/bottom-anchored-scroll-body-C8n22V_o.js.br +0 -0
- package/app/dist/assets/bottom-anchored-scroll-body-C8n22V_o.js.gz +0 -0
- package/app/dist/assets/browser-url-B0SjaYti.js.br +0 -0
- package/app/dist/assets/browser-url-B0SjaYti.js.gz +0 -0
- package/app/dist/assets/checkbox-Ct38DhHB.js.br +0 -0
- package/app/dist/assets/checkbox-Ct38DhHB.js.gz +0 -0
- package/app/dist/assets/code-loading-skeletons-C_099GEq.js.br +0 -5
- package/app/dist/assets/code-loading-skeletons-C_099GEq.js.gz +0 -0
- package/app/dist/assets/detail-card-Cj628JNK.js.br +0 -0
- package/app/dist/assets/detail-card-Cj628JNK.js.gz +0 -0
- package/app/dist/assets/diff-stats-tally-MtORWItG.js.br +0 -0
- package/app/dist/assets/diff-stats-tally-MtORWItG.js.gz +0 -0
- package/app/dist/assets/environment-mutations-rP4eROm2.js.br +0 -0
- package/app/dist/assets/environment-mutations-rP4eROm2.js.gz +0 -0
- package/app/dist/assets/environment-workspace-display-O1JRHfbV.js.br +0 -0
- package/app/dist/assets/environment-workspace-display-O1JRHfbV.js.gz +0 -0
- package/app/dist/assets/event-code-block-DqUZCAii.js.br +0 -0
- package/app/dist/assets/event-code-block-DqUZCAii.js.gz +0 -0
- package/app/dist/assets/expandable-text-herJC70e.js.br +0 -0
- package/app/dist/assets/expandable-text-herJC70e.js.gz +0 -0
- package/app/dist/assets/file-path-link-Cni9Azi2.js.br +0 -0
- package/app/dist/assets/file-path-link-Cni9Azi2.js.gz +0 -0
- package/app/dist/assets/host-mutations-Ckc-eVys.js.br +0 -0
- package/app/dist/assets/host-mutations-Ckc-eVys.js.gz +0 -0
- package/app/dist/assets/icon-extended-DDFkslJU.js.br +0 -0
- package/app/dist/assets/icon-extended-DDFkslJU.js.gz +0 -0
- package/app/dist/assets/image-lightbox-BW1bqQJM.js.br +0 -0
- package/app/dist/assets/image-lightbox-BW1bqQJM.js.gz +0 -0
- package/app/dist/assets/index-BBxUiLNy.js +0 -395
- package/app/dist/assets/index-BBxUiLNy.js.br +0 -0
- package/app/dist/assets/index-BBxUiLNy.js.gz +0 -0
- package/app/dist/assets/inline-rename-editor-wjwfk7v2.js.br +0 -0
- package/app/dist/assets/inline-rename-editor-wjwfk7v2.js.gz +0 -0
- package/app/dist/assets/launcherRow-rIW7Z6Xm.js.br +0 -0
- package/app/dist/assets/launcherRow-rIW7Z6Xm.js.gz +0 -0
- package/app/dist/assets/localhost-link-rewrite-description-Bovg3W--.js.br +0 -0
- package/app/dist/assets/localhost-link-rewrite-description-Bovg3W--.js.gz +0 -0
- package/app/dist/assets/machine-provider-queries-CRlWTEz7.js.br +0 -0
- package/app/dist/assets/machine-provider-queries-CRlWTEz7.js.gz +0 -0
- package/app/dist/assets/markdown-html-B-Kyh3zI.js.br +0 -0
- package/app/dist/assets/markdown-html-B-Kyh3zI.js.gz +0 -0
- package/app/dist/assets/markdown-local-file-link-C89PR8d5.js.br +0 -0
- package/app/dist/assets/markdown-local-file-link-C89PR8d5.js.gz +0 -0
- package/app/dist/assets/markdown-preview-B7BmqIlu.js.br +0 -0
- package/app/dist/assets/markdown-preview-B7BmqIlu.js.gz +0 -0
- package/app/dist/assets/markdown-prompt-mentions-B0JRhgrI.js.br +0 -0
- package/app/dist/assets/markdown-prompt-mentions-B0JRhgrI.js.gz +0 -0
- package/app/dist/assets/model-load-error-message-B-HKqgUD.js.br +0 -0
- package/app/dist/assets/model-load-error-message-B-HKqgUD.js.gz +0 -0
- package/app/dist/assets/onboarding-telemetry-C21cbjI_.js +0 -1
- package/app/dist/assets/open-in-editor-button-CQGreiCk.js.br +0 -0
- package/app/dist/assets/open-in-editor-button-CQGreiCk.js.gz +0 -0
- package/app/dist/assets/page-shell-BHTOdeQn.js.br +0 -0
- package/app/dist/assets/page-shell-BHTOdeQn.js.gz +0 -0
- package/app/dist/assets/pierre-worker-pool-Bm9cLA-c.js.br +0 -0
- package/app/dist/assets/pierre-worker-pool-Bm9cLA-c.js.gz +0 -0
- package/app/dist/assets/plugin-detail-navigation-CmSGTNyL.js.br +0 -0
- package/app/dist/assets/plugin-detail-navigation-CmSGTNyL.js.gz +0 -0
- package/app/dist/assets/plugin-frontend-BdQdYbWd.js.br +0 -0
- package/app/dist/assets/plugin-frontend-BdQdYbWd.js.gz +0 -0
- package/app/dist/assets/plugin-ui-DyNDyPD9.js.br +0 -0
- package/app/dist/assets/plugin-ui-DyNDyPD9.js.gz +0 -0
- package/app/dist/assets/queued-editor-typeahead-layout-BKui5z7C.js.br +0 -0
- package/app/dist/assets/queued-editor-typeahead-layout-BKui5z7C.js.gz +0 -0
- package/app/dist/assets/queued-messages-layout-BuEilXwP.js.br +0 -0
- package/app/dist/assets/queued-messages-layout-BuEilXwP.js.gz +0 -0
- package/app/dist/assets/resource-list-B6MkAu8v.js.br +0 -0
- package/app/dist/assets/resource-list-B6MkAu8v.js.gz +0 -0
- package/app/dist/assets/root-compose-create-preference-DDv947dq.js +0 -1
- package/app/dist/assets/settings-nav-DbICcozy.js.br +0 -0
- package/app/dist/assets/settings-nav-DbICcozy.js.gz +0 -0
- package/app/dist/assets/settings-sections-Cq0VX9E8.js.br +0 -0
- package/app/dist/assets/settings-sections-Cq0VX9E8.js.gz +0 -0
- package/app/dist/assets/sidebarTouchSensor-D7jKXrfM.js.br +0 -0
- package/app/dist/assets/sidebarTouchSensor-D7jKXrfM.js.gz +0 -0
- package/app/dist/assets/switch-CzvlSesf.js.br +0 -0
- package/app/dist/assets/switch-CzvlSesf.js.gz +0 -0
- package/app/dist/assets/thread-event-parser-BqVpKC6z.js.br +0 -0
- package/app/dist/assets/thread-event-parser-BqVpKC6z.js.gz +0 -0
- package/app/dist/assets/thread-panel-queries-C3MI4mdc.js.br +0 -0
- package/app/dist/assets/thread-panel-queries-C3MI4mdc.js.gz +0 -0
- package/app/dist/assets/thread-runtime-mutations-Cr1H7KSz.js.br +0 -0
- package/app/dist/assets/thread-runtime-mutations-Cr1H7KSz.js.gz +0 -0
- package/app/dist/assets/thread-terminal-queries-B4JkOWS2.js.br +0 -0
- package/app/dist/assets/thread-terminal-queries-B4JkOWS2.js.gz +0 -0
- package/app/dist/assets/threadRecentItems-DI2mgj7S.js.br +0 -0
- package/app/dist/assets/threadRecentItems-DI2mgj7S.js.gz +0 -0
- package/app/dist/assets/threadWorkspaceOpenPath-BQgtUYL5.js.br +0 -0
- package/app/dist/assets/threadWorkspaceOpenPath-BQgtUYL5.js.gz +0 -0
- package/app/dist/assets/title-bar-scroll-fade-CxbgbTcm.js.br +0 -0
- package/app/dist/assets/title-bar-scroll-fade-CxbgbTcm.js.gz +0 -0
- package/app/dist/assets/use-hover-popover-CyIdak3c.js.br +0 -0
- package/app/dist/assets/use-hover-popover-CyIdak3c.js.gz +0 -0
- package/app/dist/assets/useElementWidth-CL3Nb-eq.js.br +0 -0
- package/app/dist/assets/useElementWidth-CL3Nb-eq.js.gz +0 -0
- package/app/dist/assets/useLocalOpenTargets-yzd9-Ceh.js.br +0 -0
- package/app/dist/assets/useLocalOpenTargets-yzd9-Ceh.js.gz +0 -0
- package/app/dist/assets/usePanelResizeSnap-dys9IwEk.js.br +0 -0
- package/app/dist/assets/usePanelResizeSnap-dys9IwEk.js.gz +0 -0
- package/app/dist/assets/usePanelTerminals-BN8UCJFO.js.br +0 -0
- package/app/dist/assets/usePanelTerminals-BN8UCJFO.js.gz +0 -0
- package/app/dist/assets/usePathSuggestions-DkeFAE7l.js.br +0 -0
- package/app/dist/assets/usePathSuggestions-DkeFAE7l.js.gz +0 -0
- package/app/dist/assets/useResolvedLiveFileTarget-43fAKgDx.js.br +0 -0
- package/app/dist/assets/useResolvedLiveFileTarget-43fAKgDx.js.gz +0 -0
- package/app/dist/assets/useThreadTerminalController-DcWLbe8W.js.br +0 -0
- package/app/dist/assets/useThreadTerminalController-DcWLbe8W.js.gz +0 -0
- package/app/dist/assets/workspace-change-summary-Bd3p-LXz.js.br +0 -0
- package/app/dist/assets/workspace-change-summary-Bd3p-LXz.js.gz +0 -0
- package/app/dist/assets/workspace-checkout-display-DMp28yCr.js.br +0 -0
- package/app/dist/assets/workspace-checkout-display-DMp28yCr.js.gz +0 -0
- package/host-daemon/dist/bb-chunks/chunk-CLMP7PJ2.js +0 -2
- package/host-daemon/dist/bb-chunks/chunk-SDZLOCRA.js +0 -2186
- package/host-daemon/dist/bb-chunks/project-J3U36Y4U.js +0 -2
- package/host-daemon/dist/bb-chunks/thread-event-parser-VC3WTCLZ.js +0 -2
|
@@ -1,2186 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{A as ht,B as gt,C as ft,E as bs,F as Me,G as bt,I as ys,K as vs,O as Ss,U as xs,V as Rs,W as Ts,X as ws,a as as,b as S,c as je,e as O,f as K,g as L,h as _e,i as Tn,j as ls,k as _,m as ds,n as cs,o as pt,p as ps,s as us,u as ms,v as hs,w as ut,x as gs,y as pe,z as mt}from"./chunk-QE47NRKX.js";import{a as fs,d as ks}from"./chunk-ZT24MY2V.js";import{a as e}from"./chunk-7LJFYNRQ.js";import{a as R,b as P,d as J}from"./chunk-5PWLIQO6.js";var F=P((tA,xa)=>{"use strict";var va=["nodebuffer","arraybuffer","fragments"],Sa=typeof Blob<"u";Sa&&va.push("blob");xa.exports={BINARY_TYPES:va,CLOSE_TIMEOUT:3e4,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:Sa,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var tt=P((nA,Yt)=>{"use strict";var{EMPTY_BUFFER:$g}=F(),jr=Buffer[Symbol.species];function Qg(n,t){if(n.length===0)return $g;if(n.length===1)return n[0];let r=Buffer.allocUnsafe(t),s=0;for(let i=0;i<n.length;i++){let a=n[i];r.set(a,s),s+=a.length}return s<t?new jr(r.buffer,r.byteOffset,s):r}function Ra(n,t,r,s,i){for(let a=0;a<i;a++)r[s+a]=n[a]^t[a&3]}function Ta(n,t){for(let r=0;r<n.length;r++)n[r]^=t[r&3]}function Gg(n){return n.length===n.buffer.byteLength?n.buffer:n.buffer.slice(n.byteOffset,n.byteOffset+n.length)}function _r(n){if(_r.readOnly=!0,Buffer.isBuffer(n))return n;let t;return n instanceof ArrayBuffer?t=new jr(n):ArrayBuffer.isView(n)?t=new jr(n.buffer,n.byteOffset,n.byteLength):(t=Buffer.from(n),_r.readOnly=!1),t}Yt.exports={concat:Qg,mask:Ra,toArrayBuffer:Gg,toBuffer:_r,unmask:Ta};if(!process.env.WS_NO_BUFFER_UTIL)try{let n=R("bufferutil");Yt.exports.mask=function(t,r,s,i,a){a<48?Ra(t,r,s,i,a):n.mask(t,r,s,i,a)},Yt.exports.unmask=function(t,r){t.length<32?Ta(t,r):n.unmask(t,r)}}catch{}});var Pa=P((rA,ka)=>{"use strict";var wa=Symbol("kDone"),Mr=Symbol("kRun"),Dr=class{constructor(t){this[wa]=()=>{this.pending--,this[Mr]()},this.concurrency=t||1/0,this.jobs=[],this.pending=0}add(t){this.jobs.push(t),this[Mr]()}[Mr](){if(this.pending!==this.concurrency&&this.jobs.length){let t=this.jobs.shift();this.pending++,t(this[wa])}}};ka.exports=Dr});var Te=P((sA,Ca)=>{"use strict";var nt=R("zlib"),Aa=tt(),Jg=Pa(),{kStatusCode:Ia}=F(),Kg=Buffer[Symbol.species],Vg=Buffer.from([0,0,255,255]),en=Symbol("permessage-deflate"),W=Symbol("total-length"),xe=Symbol("callback"),X=Symbol("buffers"),Re=Symbol("error"),Zt,Or=class{constructor(t){if(this._options=t||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,!Zt){let r=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;Zt=new Jg(r)}}static get extensionName(){return"permessage-deflate"}offer(){let t={};return this._options.serverNoContextTakeover&&(t.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(t.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(t.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?t.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(t.client_max_window_bits=!0),t}accept(t){return t=this.normalizeParams(t),this.params=this._isServer?this.acceptAsServer(t):this.acceptAsClient(t),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let t=this._deflate[xe];this._deflate.close(),this._deflate=null,t&&t(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(t){let r=this._options,s=t.find(i=>!(r.serverNoContextTakeover===!1&&i.server_no_context_takeover||i.server_max_window_bits&&(r.serverMaxWindowBits===!1||typeof r.serverMaxWindowBits=="number"&&r.serverMaxWindowBits>i.server_max_window_bits)||typeof r.clientMaxWindowBits=="number"&&!i.client_max_window_bits));if(!s)throw new Error("None of the extension offers can be accepted");return r.serverNoContextTakeover&&(s.server_no_context_takeover=!0),r.clientNoContextTakeover&&(s.client_no_context_takeover=!0),typeof r.serverMaxWindowBits=="number"&&(s.server_max_window_bits=r.serverMaxWindowBits),typeof r.clientMaxWindowBits=="number"?s.client_max_window_bits=r.clientMaxWindowBits:(s.client_max_window_bits===!0||r.clientMaxWindowBits===!1)&&delete s.client_max_window_bits,s}acceptAsClient(t){let r=t[0];if(this._options.clientNoContextTakeover===!1&&r.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!r.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(r.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&r.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return r}normalizeParams(t){return t.forEach(r=>{Object.keys(r).forEach(s=>{let i=r[s];if(i.length>1)throw new Error(`Parameter "${s}" must have only a single value`);if(i=i[0],s==="client_max_window_bits"){if(i!==!0){let a=+i;if(!Number.isInteger(a)||a<8||a>15)throw new TypeError(`Invalid value for parameter "${s}": ${i}`);i=a}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${s}": ${i}`)}else if(s==="server_max_window_bits"){let a=+i;if(!Number.isInteger(a)||a<8||a>15)throw new TypeError(`Invalid value for parameter "${s}": ${i}`);i=a}else if(s==="client_no_context_takeover"||s==="server_no_context_takeover"){if(i!==!0)throw new TypeError(`Invalid value for parameter "${s}": ${i}`)}else throw new Error(`Unknown parameter "${s}"`);r[s]=i})}),t}decompress(t,r,s){Zt.add(i=>{this._decompress(t,r,(a,l)=>{i(),s(a,l)})})}compress(t,r,s){Zt.add(i=>{this._compress(t,r,(a,l)=>{i(),s(a,l)})})}_decompress(t,r,s){let i=this._isServer?"client":"server";if(!this._inflate){let a=`${i}_max_window_bits`,l=typeof this.params[a]!="number"?nt.Z_DEFAULT_WINDOWBITS:this.params[a];this._inflate=nt.createInflateRaw({...this._options.zlibInflateOptions,windowBits:l}),this._inflate[en]=this,this._inflate[W]=0,this._inflate[X]=[],this._inflate.on("error",Yg),this._inflate.on("data",Ea)}this._inflate[xe]=s,this._inflate.write(t),r&&this._inflate.write(Vg),this._inflate.flush(()=>{let a=this._inflate[Re];if(a){this._inflate.close(),this._inflate=null,s(a);return}let l=Aa.concat(this._inflate[X],this._inflate[W]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[W]=0,this._inflate[X]=[],r&&this.params[`${i}_no_context_takeover`]&&this._inflate.reset()),s(null,l)})}_compress(t,r,s){let i=this._isServer?"server":"client";if(!this._deflate){let a=`${i}_max_window_bits`,l=typeof this.params[a]!="number"?nt.Z_DEFAULT_WINDOWBITS:this.params[a];this._deflate=nt.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:l}),this._deflate[W]=0,this._deflate[X]=[],this._deflate.on("data",Xg)}this._deflate[xe]=s,this._deflate.write(t),this._deflate.flush(nt.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let a=Aa.concat(this._deflate[X],this._deflate[W]);r&&(a=new Kg(a.buffer,a.byteOffset,a.length-4)),this._deflate[xe]=null,this._deflate[W]=0,this._deflate[X]=[],r&&this.params[`${i}_no_context_takeover`]&&this._deflate.reset(),s(null,a)})}};Ca.exports=Or;function Xg(n){this[X].push(n),this[W]+=n.length}function Ea(n){if(this[W]+=n.length,this[en]._maxPayload<1||this[W]<=this[en]._maxPayload){this[X].push(n);return}this[Re]=new RangeError("Max payload size exceeded"),this[Re].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[Re][Ia]=1009,this.removeListener("data",Ea),this.reset()}function Yg(n){if(this[en]._inflate=null,this[Re]){this[xe](this[Re]);return}n[Ia]=1007,this[xe](n)}});var we=P((iA,tn)=>{"use strict";var{isUtf8:ja}=R("buffer"),{hasBlob:Zg}=F(),ef=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function tf(n){return n>=1e3&&n<=1014&&n!==1004&&n!==1005&&n!==1006||n>=3e3&&n<=4999}function Lr(n){let t=n.length,r=0;for(;r<t;)if((n[r]&128)===0)r++;else if((n[r]&224)===192){if(r+1===t||(n[r+1]&192)!==128||(n[r]&254)===192)return!1;r+=2}else if((n[r]&240)===224){if(r+2>=t||(n[r+1]&192)!==128||(n[r+2]&192)!==128||n[r]===224&&(n[r+1]&224)===128||n[r]===237&&(n[r+1]&224)===160)return!1;r+=3}else if((n[r]&248)===240){if(r+3>=t||(n[r+1]&192)!==128||(n[r+2]&192)!==128||(n[r+3]&192)!==128||n[r]===240&&(n[r+1]&240)===128||n[r]===244&&n[r+1]>143||n[r]>244)return!1;r+=4}else return!1;return!0}function nf(n){return Zg&&typeof n=="object"&&typeof n.arrayBuffer=="function"&&typeof n.type=="string"&&typeof n.stream=="function"&&(n[Symbol.toStringTag]==="Blob"||n[Symbol.toStringTag]==="File")}tn.exports={isBlob:nf,isValidStatusCode:tf,isValidUTF8:Lr,tokenChars:ef};if(ja)tn.exports.isValidUTF8=function(n){return n.length<24?Lr(n):ja(n)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let n=R("utf-8-validate");tn.exports.isValidUTF8=function(t){return t.length<32?Lr(t):n(t)}}catch{}});var Nr=P((oA,Ua)=>{"use strict";var{Writable:rf}=R("stream"),_a=Te(),{BINARY_TYPES:sf,EMPTY_BUFFER:Ma,kStatusCode:of,kWebSocket:af}=F(),{concat:qr,toArrayBuffer:lf,unmask:df}=tt(),{isValidStatusCode:cf,isValidUTF8:Da}=we(),nn=Buffer[Symbol.species],C=0,Oa=1,La=2,qa=3,Ur=4,Br=5,rn=6,zr=class extends rf{constructor(t={}){super(),this._allowSynchronousEvents=t.allowSynchronousEvents!==void 0?t.allowSynchronousEvents:!0,this._binaryType=t.binaryType||sf[0],this._extensions=t.extensions||{},this._isServer=!!t.isServer,this._maxBufferedChunks=t.maxBufferedChunks|0,this._maxFragments=t.maxFragments|0,this._maxPayload=t.maxPayload|0,this._skipUTF8Validation=!!t.skipUTF8Validation,this[af]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=C}_write(t,r,s){if(this._opcode===8&&this._state==C)return s();if(this._maxBufferedChunks>0&&this._buffers.length>=this._maxBufferedChunks){s(this.createError(RangeError,"Too many buffered chunks",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS"));return}this._bufferedBytes+=t.length,this._buffers.push(t),this.startLoop(s)}consume(t){if(this._bufferedBytes-=t,t===this._buffers[0].length)return this._buffers.shift();if(t<this._buffers[0].length){let s=this._buffers[0];return this._buffers[0]=new nn(s.buffer,s.byteOffset+t,s.length-t),new nn(s.buffer,s.byteOffset,t)}let r=Buffer.allocUnsafe(t);do{let s=this._buffers[0],i=r.length-t;t>=s.length?r.set(this._buffers.shift(),i):(r.set(new Uint8Array(s.buffer,s.byteOffset,t),i),this._buffers[0]=new nn(s.buffer,s.byteOffset+t,s.length-t)),t-=s.length}while(t>0);return r}startLoop(t){this._loop=!0;do switch(this._state){case C:this.getInfo(t);break;case Oa:this.getPayloadLength16(t);break;case La:this.getPayloadLength64(t);break;case qa:this.getMask();break;case Ur:this.getData(t);break;case Br:case rn:this._loop=!1;return}while(this._loop);this._errored||t()}getInfo(t){if(this._bufferedBytes<2){this._loop=!1;return}let r=this.consume(2);if((r[0]&48)!==0){let i=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");t(i);return}let s=(r[0]&64)===64;if(s&&!this._extensions[_a.extensionName]){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");t(i);return}if(this._fin=(r[0]&128)===128,this._opcode=r[0]&15,this._payloadLength=r[1]&127,this._opcode===0){if(s){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");t(i);return}if(!this._fragmented){let i=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");t(i);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let i=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");t(i);return}this._compressed=s}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let i=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");t(i);return}if(s){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");t(i);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let i=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");t(i);return}}else{let i=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");t(i);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(r[1]&128)===128,this._isServer){if(!this._masked){let i=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");t(i);return}}else if(this._masked){let i=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");t(i);return}this._payloadLength===126?this._state=Oa:this._payloadLength===127?this._state=La:this.haveLength(t)}getPayloadLength16(t){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(t)}getPayloadLength64(t){if(this._bufferedBytes<8){this._loop=!1;return}let r=this.consume(8),s=r.readUInt32BE(0);if(s>Math.pow(2,21)-1){let i=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");t(i);return}this._payloadLength=s*Math.pow(2,32)+r.readUInt32BE(4),this.haveLength(t)}haveLength(t){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let r=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");t(r);return}this._masked?this._state=qa:this._state=Ur}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=Ur}getData(t){let r=Ma;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=!1;return}r=this.consume(this._payloadLength),this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0&&df(r,this._mask)}if(this._opcode>7){this.controlMessage(r,t);return}if(this._compressed){this._state=Br,this.decompress(r,t);return}if(r.length){if(this._maxFragments>0&&this._fragments.length>=this._maxFragments){let s=this.createError(RangeError,"Too many message fragments",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS");t(s);return}this._messageLength=this._totalPayloadLength,this._fragments.push(r)}this.dataMessage(t)}decompress(t,r){this._extensions[_a.extensionName].decompress(t,this._fin,(i,a)=>{if(i)return r(i);if(a.length){if(this._messageLength+=a.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let l=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");r(l);return}if(this._maxFragments>0&&this._fragments.length>=this._maxFragments){let l=this.createError(RangeError,"Too many message fragments",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS");r(l);return}this._fragments.push(a)}this.dataMessage(r),this._state===C&&this.startLoop(r)})}dataMessage(t){if(!this._fin){this._state=C;return}let r=this._messageLength,s=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let i;this._binaryType==="nodebuffer"?i=qr(s,r):this._binaryType==="arraybuffer"?i=lf(qr(s,r)):this._binaryType==="blob"?i=new Blob(s):i=s,this._allowSynchronousEvents?(this.emit("message",i,!0),this._state=C):(this._state=rn,setImmediate(()=>{this.emit("message",i,!0),this._state=C,this.startLoop(t)}))}else{let i=qr(s,r);if(!this._skipUTF8Validation&&!Da(i)){let a=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");t(a);return}this._state===Br||this._allowSynchronousEvents?(this.emit("message",i,!1),this._state=C):(this._state=rn,setImmediate(()=>{this.emit("message",i,!1),this._state=C,this.startLoop(t)}))}}controlMessage(t,r){if(this._opcode===8){if(t.length===0)this._loop=!1,this.emit("conclude",1005,Ma),this.end();else{let s=t.readUInt16BE(0);if(!cf(s)){let a=this.createError(RangeError,`invalid status code ${s}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");r(a);return}let i=new nn(t.buffer,t.byteOffset+2,t.length-2);if(!this._skipUTF8Validation&&!Da(i)){let a=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");r(a);return}this._loop=!1,this.emit("conclude",s,i),this.end()}this._state=C;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",t),this._state=C):(this._state=rn,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",t),this._state=C,this.startLoop(r)}))}createError(t,r,s,i,a){this._loop=!1,this._errored=!0;let l=new t(s?`Invalid WebSocket frame: ${r}`:r);return Error.captureStackTrace(l,this.createError),l.code=a,l[of]=i,l}};Ua.exports=zr});var Wr=P((lA,Na)=>{"use strict";var{Duplex:aA}=R("stream"),{randomFillSync:pf}=R("crypto"),{types:{isUint8Array:uf}}=R("util"),Ba=Te(),{EMPTY_BUFFER:mf,kWebSocket:hf,NOOP:gf}=F(),{isBlob:ke,isValidStatusCode:ff}=we(),{mask:za,toBuffer:re}=tt(),j=Symbol("kByteLength"),bf=Buffer.alloc(4),sn=8*1024,se,Pe=sn,D=0,yf=1,vf=2,Hr=class n{constructor(t,r,s){this._extensions=r||{},s&&(this._generateMask=s,this._maskBuffer=Buffer.alloc(4)),this._socket=t,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=D,this.onerror=gf,this[hf]=void 0}static frame(t,r){let s,i=!1,a=2,l=!1;r.mask&&(s=r.maskBuffer||bf,r.generateMask?r.generateMask(s):(Pe===sn&&(se===void 0&&(se=Buffer.alloc(sn)),pf(se,0,sn),Pe=0),s[0]=se[Pe++],s[1]=se[Pe++],s[2]=se[Pe++],s[3]=se[Pe++]),l=(s[0]|s[1]|s[2]|s[3])===0,a=6);let p;typeof t=="string"?(!r.mask||l)&&r[j]!==void 0?p=r[j]:(t=Buffer.from(t),p=t.length):(p=t.length,i=r.mask&&r.readOnly&&!l);let m=p;p>=65536?(a+=8,m=127):p>125&&(a+=2,m=126);let o=Buffer.allocUnsafe(i?p+a:a);return o[0]=r.fin?r.opcode|128:r.opcode,r.rsv1&&(o[0]|=64),o[1]=m,m===126?o.writeUInt16BE(p,2):m===127&&(o[2]=o[3]=0,o.writeUIntBE(p,4,6)),r.mask?(o[1]|=128,o[a-4]=s[0],o[a-3]=s[1],o[a-2]=s[2],o[a-1]=s[3],l?[o,t]:i?(za(t,s,o,a,p),[o]):(za(t,s,t,0,p),[o,t])):[o,t]}close(t,r,s,i){let a;if(t===void 0)a=mf;else{if(typeof t!="number"||!ff(t))throw new TypeError("First argument must be a valid error code number");if(r===void 0||!r.length)a=Buffer.allocUnsafe(2),a.writeUInt16BE(t,0);else{let p=Buffer.byteLength(r);if(p>123)throw new RangeError("The message must not be greater than 123 bytes");if(a=Buffer.allocUnsafe(2+p),a.writeUInt16BE(t,0),typeof r=="string")a.write(r,2);else if(uf(r))a.set(r,2);else throw new TypeError("Second argument must be a string or a Uint8Array")}}let l={[j]:a.length,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state!==D?this.enqueue([this.dispatch,a,!1,l,i]):this.sendFrame(n.frame(a,l),i)}ping(t,r,s){let i,a;if(typeof t=="string"?(i=Buffer.byteLength(t),a=!1):ke(t)?(i=t.size,a=!1):(t=re(t),i=t.length,a=re.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");let l={[j]:i,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:9,readOnly:a,rsv1:!1};ke(t)?this._state!==D?this.enqueue([this.getBlobData,t,!1,l,s]):this.getBlobData(t,!1,l,s):this._state!==D?this.enqueue([this.dispatch,t,!1,l,s]):this.sendFrame(n.frame(t,l),s)}pong(t,r,s){let i,a;if(typeof t=="string"?(i=Buffer.byteLength(t),a=!1):ke(t)?(i=t.size,a=!1):(t=re(t),i=t.length,a=re.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");let l={[j]:i,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:10,readOnly:a,rsv1:!1};ke(t)?this._state!==D?this.enqueue([this.getBlobData,t,!1,l,s]):this.getBlobData(t,!1,l,s):this._state!==D?this.enqueue([this.dispatch,t,!1,l,s]):this.sendFrame(n.frame(t,l),s)}send(t,r,s){let i=this._extensions[Ba.extensionName],a=r.binary?2:1,l=r.compress,p,m;typeof t=="string"?(p=Buffer.byteLength(t),m=!1):ke(t)?(p=t.size,m=!1):(t=re(t),p=t.length,m=re.readOnly),this._firstFragment?(this._firstFragment=!1,l&&i&&i.params[i._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(l=p>=i._threshold),this._compress=l):(l=!1,a=0),r.fin&&(this._firstFragment=!0);let o={[j]:p,fin:r.fin,generateMask:this._generateMask,mask:r.mask,maskBuffer:this._maskBuffer,opcode:a,readOnly:m,rsv1:l};ke(t)?this._state!==D?this.enqueue([this.getBlobData,t,this._compress,o,s]):this.getBlobData(t,this._compress,o,s):this._state!==D?this.enqueue([this.dispatch,t,this._compress,o,s]):this.dispatch(t,this._compress,o,s)}getBlobData(t,r,s,i){this._bufferedBytes+=s[j],this._state=vf,t.arrayBuffer().then(a=>{if(this._socket.destroyed){let p=new Error("The socket was closed while the blob was being read");process.nextTick(Fr,this,p,i);return}this._bufferedBytes-=s[j];let l=re(a);r?this.dispatch(l,r,s,i):(this._state=D,this.sendFrame(n.frame(l,s),i),this.dequeue())}).catch(a=>{process.nextTick(Sf,this,a,i)})}dispatch(t,r,s,i){if(!r){this.sendFrame(n.frame(t,s),i);return}let a=this._extensions[Ba.extensionName];this._bufferedBytes+=s[j],this._state=yf,a.compress(t,s.fin,(l,p)=>{if(this._socket.destroyed){let m=new Error("The socket was closed while data was being compressed");Fr(this,m,i);return}this._bufferedBytes-=s[j],this._state=D,s.readOnly=!1,this.sendFrame(n.frame(p,s),i),this.dequeue()})}dequeue(){for(;this._state===D&&this._queue.length;){let t=this._queue.shift();this._bufferedBytes-=t[3][j],Reflect.apply(t[0],this,t.slice(1))}}enqueue(t){this._bufferedBytes+=t[3][j],this._queue.push(t)}sendFrame(t,r){t.length===2?(this._socket.cork(),this._socket.write(t[0]),this._socket.write(t[1],r),this._socket.uncork()):this._socket.write(t[0],r)}};Na.exports=Hr;function Fr(n,t,r){typeof r=="function"&&r(t);for(let s=0;s<n._queue.length;s++){let i=n._queue[s],a=i[i.length-1];typeof a=="function"&&a(t)}}function Sf(n,t,r){Fr(n,t,r),n.onerror(t)}});var Va=P((dA,Ka)=>{"use strict";var{kForOnEventAttribute:rt,kListener:$r}=F(),Ha=Symbol("kCode"),Fa=Symbol("kData"),Wa=Symbol("kError"),$a=Symbol("kMessage"),Qa=Symbol("kReason"),Ae=Symbol("kTarget"),Ga=Symbol("kType"),Ja=Symbol("kWasClean"),$=class{constructor(t){this[Ae]=null,this[Ga]=t}get target(){return this[Ae]}get type(){return this[Ga]}};Object.defineProperty($.prototype,"target",{enumerable:!0});Object.defineProperty($.prototype,"type",{enumerable:!0});var ie=class extends ${constructor(t,r={}){super(t),this[Ha]=r.code===void 0?0:r.code,this[Qa]=r.reason===void 0?"":r.reason,this[Ja]=r.wasClean===void 0?!1:r.wasClean}get code(){return this[Ha]}get reason(){return this[Qa]}get wasClean(){return this[Ja]}};Object.defineProperty(ie.prototype,"code",{enumerable:!0});Object.defineProperty(ie.prototype,"reason",{enumerable:!0});Object.defineProperty(ie.prototype,"wasClean",{enumerable:!0});var Ie=class extends ${constructor(t,r={}){super(t),this[Wa]=r.error===void 0?null:r.error,this[$a]=r.message===void 0?"":r.message}get error(){return this[Wa]}get message(){return this[$a]}};Object.defineProperty(Ie.prototype,"error",{enumerable:!0});Object.defineProperty(Ie.prototype,"message",{enumerable:!0});var st=class extends ${constructor(t,r={}){super(t),this[Fa]=r.data===void 0?null:r.data}get data(){return this[Fa]}};Object.defineProperty(st.prototype,"data",{enumerable:!0});var xf={addEventListener(n,t,r={}){for(let i of this.listeners(n))if(!r[rt]&&i[$r]===t&&!i[rt])return;let s;if(n==="message")s=function(a,l){let p=new st("message",{data:l?a:a.toString()});p[Ae]=this,on(t,this,p)};else if(n==="close")s=function(a,l){let p=new ie("close",{code:a,reason:l.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});p[Ae]=this,on(t,this,p)};else if(n==="error")s=function(a){let l=new Ie("error",{error:a,message:a.message});l[Ae]=this,on(t,this,l)};else if(n==="open")s=function(){let a=new $("open");a[Ae]=this,on(t,this,a)};else return;s[rt]=!!r[rt],s[$r]=t,r.once?this.once(n,s):this.on(n,s)},removeEventListener(n,t){for(let r of this.listeners(n))if(r[$r]===t&&!r[rt]){this.removeListener(n,r);break}}};Ka.exports={CloseEvent:ie,ErrorEvent:Ie,Event:$,EventTarget:xf,MessageEvent:st};function on(n,t,r){typeof n=="object"&&n.handleEvent?n.handleEvent.call(n,r):n.call(t,r)}});var an=P((cA,Xa)=>{"use strict";var{tokenChars:it}=we();function U(n,t,r){n[t]===void 0?n[t]=[r]:n[t].push(r)}function Rf(n){let t=Object.create(null),r=Object.create(null),s=!1,i=!1,a=!1,l,p,m=-1,o=-1,g=-1,h=0;for(;h<n.length;h++)if(o=n.charCodeAt(h),l===void 0)if(g===-1&&it[o]===1)m===-1&&(m=h);else if(h!==0&&(o===32||o===9))g===-1&&m!==-1&&(g=h);else if(o===59||o===44){if(m===-1)throw new SyntaxError(`Unexpected character at index ${h}`);g===-1&&(g=h);let y=n.slice(m,g);o===44?(U(t,y,r),r=Object.create(null)):l=y,m=g=-1}else throw new SyntaxError(`Unexpected character at index ${h}`);else if(p===void 0)if(g===-1&&it[o]===1)m===-1&&(m=h);else if(o===32||o===9)g===-1&&m!==-1&&(g=h);else if(o===59||o===44){if(m===-1)throw new SyntaxError(`Unexpected character at index ${h}`);g===-1&&(g=h),U(r,n.slice(m,g),!0),o===44&&(U(t,l,r),r=Object.create(null),l=void 0),m=g=-1}else if(o===61&&m!==-1&&g===-1)p=n.slice(m,h),m=g=-1;else throw new SyntaxError(`Unexpected character at index ${h}`);else if(i){if(it[o]!==1)throw new SyntaxError(`Unexpected character at index ${h}`);m===-1?m=h:s||(s=!0),i=!1}else if(a)if(it[o]===1)m===-1&&(m=h);else if(o===34&&m!==-1)a=!1,g=h;else if(o===92)i=!0;else throw new SyntaxError(`Unexpected character at index ${h}`);else if(o===34&&n.charCodeAt(h-1)===61)a=!0;else if(g===-1&&it[o]===1)m===-1&&(m=h);else if(m!==-1&&(o===32||o===9))g===-1&&(g=h);else if(o===59||o===44){if(m===-1)throw new SyntaxError(`Unexpected character at index ${h}`);g===-1&&(g=h);let y=n.slice(m,g);s&&(y=y.replace(/\\/g,""),s=!1),U(r,p,y),o===44&&(U(t,l,r),r=Object.create(null),l=void 0),p=void 0,m=g=-1}else throw new SyntaxError(`Unexpected character at index ${h}`);if(m===-1||a||o===32||o===9)throw new SyntaxError("Unexpected end of input");g===-1&&(g=h);let b=n.slice(m,g);return l===void 0?U(t,b,r):(p===void 0?U(r,b,!0):s?U(r,p,b.replace(/\\/g,"")):U(r,p,b),U(t,l,r)),t}function Tf(n){return Object.keys(n).map(t=>{let r=n[t];return Array.isArray(r)||(r=[r]),r.map(s=>[t].concat(Object.keys(s).map(i=>{let a=s[i];return Array.isArray(a)||(a=[a]),a.map(l=>l===!0?i:`${i}=${l}`).join("; ")})).join("; ")).join(", ")}).join(", ")}Xa.exports={format:Tf,parse:Rf}});var pn=P((mA,dl)=>{"use strict";var wf=R("events"),kf=R("https"),Pf=R("http"),el=R("net"),Af=R("tls"),{randomBytes:If,createHash:Ef}=R("crypto"),{Duplex:pA,Readable:uA}=R("stream"),{URL:Qr}=R("url"),Y=Te(),Cf=Nr(),jf=Wr(),{isBlob:_f}=we(),{BINARY_TYPES:Ya,CLOSE_TIMEOUT:Mf,EMPTY_BUFFER:ln,GUID:Df,kForOnEventAttribute:Gr,kListener:Of,kStatusCode:Lf,kWebSocket:T,NOOP:tl}=F(),{EventTarget:{addEventListener:qf,removeEventListener:Uf}}=Va(),{format:Bf,parse:zf}=an(),{toBuffer:Nf}=tt(),nl=Symbol("kAborted"),Jr=[8,13],Q=["CONNECTING","OPEN","CLOSING","CLOSED"],Hf=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,x=class n extends wf{constructor(t,r,s){super(),this._binaryType=Ya[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=ln,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol="",this._readyState=n.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,t!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,r===void 0?r=[]:Array.isArray(r)||(typeof r=="object"&&r!==null?(s=r,r=[]):r=[r]),rl(this,t,r,s)):(this._autoPong=s.autoPong,this._closeTimeout=s.closeTimeout,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(t){Ya.includes(t)&&(this._binaryType=t,this._receiver&&(this._receiver._binaryType=t))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(t,r,s){let i=new Cf({allowSynchronousEvents:s.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxBufferedChunks:s.maxBufferedChunks,maxFragments:s.maxFragments,maxPayload:s.maxPayload,skipUTF8Validation:s.skipUTF8Validation}),a=new jf(t,this._extensions,s.generateMask);this._receiver=i,this._sender=a,this._socket=t,i[T]=this,a[T]=this,t[T]=this,i.on("conclude",$f),i.on("drain",Qf),i.on("error",Gf),i.on("message",Jf),i.on("ping",Kf),i.on("pong",Vf),a.onerror=Xf,t.setTimeout&&t.setTimeout(0),t.setNoDelay&&t.setNoDelay(),r.length>0&&t.unshift(r),t.on("close",ol),t.on("data",cn),t.on("end",al),t.on("error",ll),this._readyState=n.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=n.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[Y.extensionName]&&this._extensions[Y.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=n.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(t,r){if(this.readyState!==n.CLOSED){if(this.readyState===n.CONNECTING){A(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===n.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=n.CLOSING,this._sender.close(t,r,!this._isServer,s=>{s||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),il(this)}}pause(){this.readyState===n.CONNECTING||this.readyState===n.CLOSED||(this._paused=!0,this._socket.pause())}ping(t,r,s){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof t=="function"?(s=t,t=r=void 0):typeof r=="function"&&(s=r,r=void 0),typeof t=="number"&&(t=t.toString()),this.readyState!==n.OPEN){Kr(this,t,s);return}r===void 0&&(r=!this._isServer),this._sender.ping(t||ln,r,s)}pong(t,r,s){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof t=="function"?(s=t,t=r=void 0):typeof r=="function"&&(s=r,r=void 0),typeof t=="number"&&(t=t.toString()),this.readyState!==n.OPEN){Kr(this,t,s);return}r===void 0&&(r=!this._isServer),this._sender.pong(t||ln,r,s)}resume(){this.readyState===n.CONNECTING||this.readyState===n.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(t,r,s){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof r=="function"&&(s=r,r={}),typeof t=="number"&&(t=t.toString()),this.readyState!==n.OPEN){Kr(this,t,s);return}let i={binary:typeof t!="string",mask:!this._isServer,compress:!0,fin:!0,...r};this._extensions[Y.extensionName]||(i.compress=!1),this._sender.send(t||ln,i,s)}terminate(){if(this.readyState!==n.CLOSED){if(this.readyState===n.CONNECTING){A(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=n.CLOSING,this._socket.destroy())}}};Object.defineProperty(x,"CONNECTING",{enumerable:!0,value:Q.indexOf("CONNECTING")});Object.defineProperty(x.prototype,"CONNECTING",{enumerable:!0,value:Q.indexOf("CONNECTING")});Object.defineProperty(x,"OPEN",{enumerable:!0,value:Q.indexOf("OPEN")});Object.defineProperty(x.prototype,"OPEN",{enumerable:!0,value:Q.indexOf("OPEN")});Object.defineProperty(x,"CLOSING",{enumerable:!0,value:Q.indexOf("CLOSING")});Object.defineProperty(x.prototype,"CLOSING",{enumerable:!0,value:Q.indexOf("CLOSING")});Object.defineProperty(x,"CLOSED",{enumerable:!0,value:Q.indexOf("CLOSED")});Object.defineProperty(x.prototype,"CLOSED",{enumerable:!0,value:Q.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(n=>{Object.defineProperty(x.prototype,n,{enumerable:!0})});["open","error","close","message"].forEach(n=>{Object.defineProperty(x.prototype,`on${n}`,{enumerable:!0,get(){for(let t of this.listeners(n))if(t[Gr])return t[Of];return null},set(t){for(let r of this.listeners(n))if(r[Gr]){this.removeListener(n,r);break}typeof t=="function"&&this.addEventListener(n,t,{[Gr]:!0})}})});x.prototype.addEventListener=qf;x.prototype.removeEventListener=Uf;dl.exports=x;function rl(n,t,r,s){let i={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:Mf,protocolVersion:Jr[1],maxBufferedChunks:1048576,maxFragments:131072,maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...s,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(n._autoPong=i.autoPong,n._closeTimeout=i.closeTimeout,!Jr.includes(i.protocolVersion))throw new RangeError(`Unsupported protocol version: ${i.protocolVersion} (supported versions: ${Jr.join(", ")})`);let a;if(t instanceof Qr)a=t;else try{a=new Qr(t)}catch{throw new SyntaxError(`Invalid URL: ${t}`)}a.protocol==="http:"?a.protocol="ws:":a.protocol==="https:"&&(a.protocol="wss:"),n._url=a.href;let l=a.protocol==="wss:",p=a.protocol==="ws+unix:",m;if(a.protocol!=="ws:"&&!l&&!p?m=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:p&&!a.pathname?m="The URL's pathname is empty":a.hash&&(m="The URL contains a fragment identifier"),m){let u=new SyntaxError(m);if(n._redirects===0)throw u;dn(n,u);return}let o=l?443:80,g=If(16).toString("base64"),h=l?kf.request:Pf.request,b=new Set,y;if(i.createConnection=i.createConnection||(l?Wf:Ff),i.defaultPort=i.defaultPort||o,i.port=a.port||o,i.host=a.hostname.startsWith("[")?a.hostname.slice(1,-1):a.hostname,i.headers={...i.headers,"Sec-WebSocket-Version":i.protocolVersion,"Sec-WebSocket-Key":g,Connection:"Upgrade",Upgrade:"websocket"},i.path=a.pathname+a.search,i.timeout=i.handshakeTimeout,i.perMessageDeflate&&(y=new Y({...i.perMessageDeflate,isServer:!1,maxPayload:i.maxPayload}),i.headers["Sec-WebSocket-Extensions"]=Bf({[Y.extensionName]:y.offer()})),r.length){for(let u of r){if(typeof u!="string"||!Hf.test(u)||b.has(u))throw new SyntaxError("An invalid or duplicated subprotocol was specified");b.add(u)}i.headers["Sec-WebSocket-Protocol"]=r.join(",")}if(i.origin&&(i.protocolVersion<13?i.headers["Sec-WebSocket-Origin"]=i.origin:i.headers.Origin=i.origin),(a.username||a.password)&&(i.auth=`${a.username}:${a.password}`),p){let u=i.path.split(":");i.socketPath=u[0],i.path=u[1]}let d;if(i.followRedirects){if(n._redirects===0){n._originalIpc=p,n._originalSecure=l,n._originalHostOrSocketPath=p?i.socketPath:a.host;let u=s&&s.headers;if(s={...s,headers:{}},u)for(let[f,v]of Object.entries(u))s.headers[f.toLowerCase()]=v}else if(n.listenerCount("redirect")===0){let u=p?n._originalIpc?i.socketPath===n._originalHostOrSocketPath:!1:n._originalIpc?!1:a.host===n._originalHostOrSocketPath;(!u||n._originalSecure&&!l)&&(delete i.headers.authorization,delete i.headers.cookie,u||delete i.headers.host,i.auth=void 0)}i.auth&&!s.headers.authorization&&(s.headers.authorization="Basic "+Buffer.from(i.auth).toString("base64")),d=n._req=h(i),n._redirects&&n.emit("redirect",n.url,d)}else d=n._req=h(i);i.timeout&&d.on("timeout",()=>{A(n,d,"Opening handshake has timed out")}),d.on("error",u=>{d===null||d[nl]||(d=n._req=null,dn(n,u))}),d.on("response",u=>{let f=u.headers.location,v=u.statusCode;if(f&&i.followRedirects&&v>=300&&v<400){if(++n._redirects>i.maxRedirects){A(n,d,"Maximum redirects exceeded");return}d.abort();let G;try{G=new Qr(f,t)}catch{let ce=new SyntaxError(`Invalid URL: ${f}`);dn(n,ce);return}rl(n,G,r,s)}else n.emit("unexpected-response",d,u)||A(n,d,`Unexpected server response: ${u.statusCode}`)}),d.on("upgrade",(u,f,v)=>{if(n.emit("upgrade",u),n.readyState!==x.CONNECTING)return;d=n._req=null;let G=u.headers.upgrade;if(G===void 0||G.toLowerCase()!=="websocket"){A(n,f,"Invalid Upgrade header");return}let ct=Ef("sha1").update(g+Df).digest("base64");if(u.headers["sec-websocket-accept"]!==ct){A(n,f,"Invalid Sec-WebSocket-Accept header");return}let ce=u.headers["sec-websocket-protocol"],Ce;if(ce!==void 0?b.size?b.has(ce)||(Ce="Server sent an invalid subprotocol"):Ce="Server sent a subprotocol but none was requested":b.size&&(Ce="Server sent no subprotocol"),Ce){A(n,f,Ce);return}ce&&(n._protocol=ce);let is=u.headers["sec-websocket-extensions"];if(is!==void 0){if(!y){A(n,f,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let xn;try{xn=zf(is)}catch{A(n,f,"Invalid Sec-WebSocket-Extensions header");return}let os=Object.keys(xn);if(os.length!==1||os[0]!==Y.extensionName){A(n,f,"Server indicated an extension that was not requested");return}try{y.accept(xn[Y.extensionName])}catch{A(n,f,"Invalid Sec-WebSocket-Extensions header");return}n._extensions[Y.extensionName]=y}n.setSocket(f,v,{allowSynchronousEvents:i.allowSynchronousEvents,generateMask:i.generateMask,maxBufferedChunks:i.maxBufferedChunks,maxFragments:i.maxFragments,maxPayload:i.maxPayload,skipUTF8Validation:i.skipUTF8Validation})}),i.finishRequest?i.finishRequest(d,n):d.end()}function dn(n,t){n._readyState=x.CLOSING,n._errorEmitted=!0,n.emit("error",t),n.emitClose()}function Ff(n){return n.path=n.socketPath,el.connect(n)}function Wf(n){return n.path=void 0,!n.servername&&n.servername!==""&&(n.servername=el.isIP(n.host)?"":n.host),Af.connect(n)}function A(n,t,r){n._readyState=x.CLOSING;let s=new Error(r);Error.captureStackTrace(s,A),t.setHeader?(t[nl]=!0,t.abort(),t.socket&&!t.socket.destroyed&&t.socket.destroy(),process.nextTick(dn,n,s)):(t.destroy(s),t.once("error",n.emit.bind(n,"error")),t.once("close",n.emitClose.bind(n)))}function Kr(n,t,r){if(t){let s=_f(t)?t.size:Nf(t).length;n._socket?n._sender._bufferedBytes+=s:n._bufferedAmount+=s}if(r){let s=new Error(`WebSocket is not open: readyState ${n.readyState} (${Q[n.readyState]})`);process.nextTick(r,s)}}function $f(n,t){let r=this[T];r._closeFrameReceived=!0,r._closeMessage=t,r._closeCode=n,r._socket[T]!==void 0&&(r._socket.removeListener("data",cn),process.nextTick(sl,r._socket),n===1005?r.close():r.close(n,t))}function Qf(){let n=this[T];n.isPaused||n._socket.resume()}function Gf(n){let t=this[T];t._socket[T]!==void 0&&(t._socket.removeListener("data",cn),process.nextTick(sl,t._socket),t.close(n[Lf])),t._errorEmitted||(t._errorEmitted=!0,t.emit("error",n))}function Za(){this[T].emitClose()}function Jf(n,t){this[T].emit("message",n,t)}function Kf(n){let t=this[T];t._autoPong&&t.pong(n,!this._isServer,tl),t.emit("ping",n)}function Vf(n){this[T].emit("pong",n)}function sl(n){n.resume()}function Xf(n){let t=this[T];t.readyState!==x.CLOSED&&(t.readyState===x.OPEN&&(t._readyState=x.CLOSING,il(t)),this._socket.end(),t._errorEmitted||(t._errorEmitted=!0,t.emit("error",n)))}function il(n){n._closeTimer=setTimeout(n._socket.destroy.bind(n._socket),n._closeTimeout)}function ol(){let n=this[T];if(this.removeListener("close",ol),this.removeListener("data",cn),this.removeListener("end",al),n._readyState=x.CLOSING,!this._readableState.endEmitted&&!n._closeFrameReceived&&!n._receiver._writableState.errorEmitted&&this._readableState.length!==0){let t=this.read(this._readableState.length);n._receiver.write(t)}n._receiver.end(),this[T]=void 0,clearTimeout(n._closeTimer),n._receiver._writableState.finished||n._receiver._writableState.errorEmitted?n.emitClose():(n._receiver.on("error",Za),n._receiver.on("finish",Za))}function cn(n){this[T]._receiver.write(n)||this.pause()}function al(){let n=this[T];n._readyState=x.CLOSING,n._receiver.end(),this.end()}function ll(){let n=this[T];this.removeListener("error",ll),this.on("error",tl),n&&(n._readyState=x.CLOSING,this.destroy())}});var ml=P((gA,ul)=>{"use strict";var hA=pn(),{Duplex:Yf}=R("stream");function cl(n){n.emit("close")}function Zf(){!this.destroyed&&this._writableState.finished&&this.destroy()}function pl(n){this.removeListener("error",pl),this.destroy(),this.listenerCount("error")===0&&this.emit("error",n)}function eb(n,t){let r=!0,s=new Yf({...t,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return n.on("message",function(a,l){let p=!l&&s._readableState.objectMode?a.toString():a;s.push(p)||n.pause()}),n.once("error",function(a){s.destroyed||(r=!1,s.destroy(a))}),n.once("close",function(){s.destroyed||s.push(null)}),s._destroy=function(i,a){if(n.readyState===n.CLOSED){a(i),process.nextTick(cl,s);return}let l=!1;n.once("error",function(m){l=!0,a(m)}),n.once("close",function(){l||a(i),process.nextTick(cl,s)}),r&&n.terminate()},s._final=function(i){if(n.readyState===n.CONNECTING){n.once("open",function(){s._final(i)});return}n._socket!==null&&(n._socket._writableState.finished?(i(),s._readableState.endEmitted&&s.destroy()):(n._socket.once("finish",function(){i()}),n.close()))},s._read=function(){n.isPaused&&n.resume()},s._write=function(i,a,l){if(n.readyState===n.CONNECTING){n.once("open",function(){s._write(i,a,l)});return}n.send(i,l)},s.on("end",Zf),s.on("error",pl),s}ul.exports=eb});var Vr=P((fA,hl)=>{"use strict";var{tokenChars:tb}=we();function nb(n){let t=new Set,r=-1,s=-1,i=0;for(i;i<n.length;i++){let l=n.charCodeAt(i);if(s===-1&&tb[l]===1)r===-1&&(r=i);else if(i!==0&&(l===32||l===9))s===-1&&r!==-1&&(s=i);else if(l===44){if(r===-1)throw new SyntaxError(`Unexpected character at index ${i}`);s===-1&&(s=i);let p=n.slice(r,s);if(t.has(p))throw new SyntaxError(`The "${p}" subprotocol is duplicated`);t.add(p),r=s=-1}else throw new SyntaxError(`Unexpected character at index ${i}`)}if(r===-1||s!==-1)throw new SyntaxError("Unexpected end of input");let a=n.slice(r,i);if(t.has(a))throw new SyntaxError(`The "${a}" subprotocol is duplicated`);return t.add(a),t}hl.exports={parse:nb}});var xl=P((yA,Sl)=>{"use strict";var rb=R("events"),un=R("http"),{Duplex:bA}=R("stream"),{createHash:sb}=R("crypto"),gl=an(),oe=Te(),ib=Vr(),ob=pn(),{CLOSE_TIMEOUT:ab,GUID:lb,kWebSocket:db}=F(),cb=/^[+/0-9A-Za-z]{22}==$/,fl=0,bl=1,vl=2,Xr=class extends rb{constructor(t,r){if(super(),t={allowSynchronousEvents:!0,autoPong:!0,maxBufferedChunks:1024*1024,maxFragments:128*1024,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,closeTimeout:ab,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:ob,...t},t.port==null&&!t.server&&!t.noServer||t.port!=null&&(t.server||t.noServer)||t.server&&t.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(t.port!=null?(this._server=un.createServer((s,i)=>{let a=un.STATUS_CODES[426];i.writeHead(426,{"Content-Length":a.length,"Content-Type":"text/plain"}),i.end(a)}),this._server.listen(t.port,t.host,t.backlog,r)):t.server&&(this._server=t.server),this._server){let s=this.emit.bind(this,"connection");this._removeListeners=pb(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(i,a,l)=>{this.handleUpgrade(i,a,l,s)}})}t.perMessageDeflate===!0&&(t.perMessageDeflate={}),t.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=t,this._state=fl}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(t){if(this._state===vl){t&&this.once("close",()=>{t(new Error("The server is not running"))}),process.nextTick(ot,this);return}if(t&&this.once("close",t),this._state!==bl)if(this._state=bl,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(ot,this):process.nextTick(ot,this);else{let r=this._server;this._removeListeners(),this._removeListeners=this._server=null,r.close(()=>{ot(this)})}}shouldHandle(t){if(this.options.path){let r=t.url.indexOf("?");if((r!==-1?t.url.slice(0,r):t.url)!==this.options.path)return!1}return!0}handleUpgrade(t,r,s,i){r.on("error",yl);let a=t.headers["sec-websocket-key"],l=t.headers.upgrade,p=+t.headers["sec-websocket-version"];if(t.method!=="GET"){ae(this,t,r,405,"Invalid HTTP method");return}if(l===void 0||l.toLowerCase()!=="websocket"){ae(this,t,r,400,"Invalid Upgrade header");return}if(a===void 0||!cb.test(a)){ae(this,t,r,400,"Missing or invalid Sec-WebSocket-Key header");return}if(p!==13&&p!==8){ae(this,t,r,400,"Missing or invalid Sec-WebSocket-Version header",{"Sec-WebSocket-Version":"13, 8"});return}if(!this.shouldHandle(t)){at(r,400);return}let m=t.headers["sec-websocket-protocol"],o=new Set;if(m!==void 0)try{o=ib.parse(m)}catch{ae(this,t,r,400,"Invalid Sec-WebSocket-Protocol header");return}let g=t.headers["sec-websocket-extensions"],h={};if(this.options.perMessageDeflate&&g!==void 0){let b=new oe({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let y=gl.parse(g);y[oe.extensionName]&&(b.accept(y[oe.extensionName]),h[oe.extensionName]=b)}catch{ae(this,t,r,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let b={origin:t.headers[`${p===8?"sec-websocket-origin":"origin"}`],secure:!!(t.socket.authorized||t.socket.encrypted),req:t};if(this.options.verifyClient.length===2){this.options.verifyClient(b,(y,d,u,f)=>{if(!y)return at(r,d||401,u,f);this.completeUpgrade(h,a,o,t,r,s,i)});return}if(!this.options.verifyClient(b))return at(r,401)}this.completeUpgrade(h,a,o,t,r,s,i)}completeUpgrade(t,r,s,i,a,l,p){if(!a.readable||!a.writable)return a.destroy();if(a[db])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>fl)return at(a,503);let o=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${sb("sha1").update(r+lb).digest("base64")}`],g=new this.options.WebSocket(null,void 0,this.options);if(s.size){let h=this.options.handleProtocols?this.options.handleProtocols(s,i):s.values().next().value;h&&(o.push(`Sec-WebSocket-Protocol: ${h}`),g._protocol=h)}if(t[oe.extensionName]){let h=t[oe.extensionName].params,b=gl.format({[oe.extensionName]:[h]});o.push(`Sec-WebSocket-Extensions: ${b}`),g._extensions=t}this.emit("headers",o,i),a.write(o.concat(`\r
|
|
3
|
-
`).join(`\r
|
|
4
|
-
`)),a.removeListener("error",yl),g.setSocket(a,l,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxBufferedChunks:this.options.maxBufferedChunks,maxFragments:this.options.maxFragments,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(g),g.on("close",()=>{this.clients.delete(g),this._shouldEmitClose&&!this.clients.size&&process.nextTick(ot,this)})),p(g,i)}};Sl.exports=Xr;function pb(n,t){for(let r of Object.keys(t))n.on(r,t[r]);return function(){for(let s of Object.keys(t))n.removeListener(s,t[s])}}function ot(n){n._state=vl,n.emit("close")}function yl(){this.destroy()}function at(n,t,r,s){r=r||un.STATUS_CODES[t],s={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(r),...s},n.once("finish",n.destroy),n.end(`HTTP/1.1 ${t} ${un.STATUS_CODES[t]}\r
|
|
5
|
-
`+Object.keys(s).map(i=>`${i}: ${s[i]}`).join(`\r
|
|
6
|
-
`)+`\r
|
|
7
|
-
\r
|
|
8
|
-
`+r)}function ae(n,t,r,s,i,a){if(n.listenerCount("wsClientError")){let l=new Error(i);Error.captureStackTrace(l,ae),n.emit("wsClientError",l,r,t)}else at(r,s,i,a)}});var od=["thread-title","commit-message","voice"],wn=e.enum(od),ad=["thread-title","commit-message"],Ps=e.enum(ad),De=e.discriminatedUnion("mode",[e.object({mode:e.literal("automatic")}).strict(),e.object({mode:e.literal("off")}).strict(),e.object({mode:e.literal("service"),pluginId:e.string().min(1),serviceId:e.string().min(1)}).strict()]),As=e.object({"thread-title":De,"commit-message":De,voice:De}).strict();var Is=e.discriminatedUnion("ready",[e.object({ready:e.literal(!0)}).strict(),e.object({ready:e.literal(!1),message:e.string().min(1)}).strict()]);var ld=["collapse","flat"],ue=e.enum(ld);var dd=/[\u0000-\u001f\u007f\\:~^?*\[]/u,cd=/[ \t]/u,pd=new Set(["AUTO_MERGE","BISECT_HEAD","CHERRY_PICK_HEAD","FETCH_HEAD","HEAD","MERGE_HEAD","ORIG_HEAD","REVERT_HEAD"]);function kn(n){let t=n.split("/");return n.length>0&&n.trim().length>0&&!n.startsWith("-")&&!n.startsWith("/")&&n!=="@"&&!pd.has(n)&&!dd.test(n)&&!cd.test(n)&&!n.includes("..")&&!n.includes("@{")&&!n.includes("//")&&!n.endsWith("/")&&!n.endsWith(".")&&t.every(r=>r.length>0&&!r.startsWith(".")&&!r.endsWith(".lock"))}var M=e.string().refine(kn,{message:"Invalid git branch name"}),Es=e.discriminatedUnion("kind",[e.object({kind:e.literal("named"),name:M}),e.object({kind:e.literal("default")})]),Pn=e.discriminatedUnion("kind",[e.object({kind:e.literal("branch"),branchName:e.string().min(1),headSha:e.string().min(1).nullable()}),e.object({kind:e.literal("detached"),headSha:e.string().min(1).nullable()}),e.object({kind:e.literal("unborn"),branchName:e.string().min(1).nullable()}),e.object({kind:e.literal("unknown"),reason:e.string().min(1)})]),ud=e.discriminatedUnion("kind",[e.object({kind:e.literal("none")}),e.object({kind:e.literal("merge"),hasConflicts:e.boolean()}),e.object({kind:e.literal("rebase"),hasConflicts:e.boolean()}),e.object({kind:e.literal("cherry-pick"),hasConflicts:e.boolean()}),e.object({kind:e.literal("revert"),hasConflicts:e.boolean()}),e.object({kind:e.literal("unknown"),reason:e.string().min(1),hasConflicts:e.boolean()})]),md=e.object({name:e.string().min(1),kind:e.enum(["local","remote","missing"])}),hd=e.enum(["equal","local-behind","local-ahead","diverged","unknown"]),gd=e.object({checkout:Pn,defaultBranch:e.string().min(1).nullable(),isWorktree:e.boolean(),defaultBranchRelation:hd.nullable(),hasUncommittedChanges:e.boolean(),operation:ud,originDefaultBranch:e.string().min(1).nullable()}),Cs=e.object({branches:e.array(e.string()),branchesTruncated:e.boolean(),remoteBranches:e.array(e.string()),remoteBranchesTruncated:e.boolean(),selectedBranch:md.nullable()}),js=gd.extend(Cs.shape);var fd=64;var bd=[0,5,10,30,60],An=e.literal(bd),yd=e.string().max(fd).refine(n=>kn(`${n}slug-thr_id`),{message:"Prefix must start a valid git branch name"}),yt=e.object({showKeyboardHints:e.boolean(),showGitChanges:e.boolean(),steerActiveThreadOnEnter:e.boolean(),terminalCopyOnSelect:e.boolean(),confirmThreadArchive:e.boolean(),showDiagnosticEvents:e.boolean(),keepHistoryAfterContextClear:e.boolean(),summarizeShellCommands:e.boolean(),providerOrder:e.array(e.string().min(1)),defaultProviderId:e.string().min(1).nullable(),providerCompletedTurnDisplay:e.record(e.string().min(1),ue),streamerMode:e.boolean(),allowFastServiceTier:e.boolean(),telemetryEnabled:e.boolean(),managedBranchPrefix:yd,idleProviderSessionTimeoutMinutes:An,machineServerUrl:e.string().url().refine(n=>{let t=new URL(n);return["http:","https:"].includes(t.protocol)&&!t.username&&!t.password}).nullable(),machineGitCredentialsEnabled:e.boolean(),defaultMachineAccess:e.string().min(1).nullable(),onboardingCompletedAt:e.string().min(1).nullable(),earlyAdopter:e.boolean()}).strict();var nv=e.array(e.string().min(1)),rv=e.union([yt.extend({idleProviderSessionTimeoutMinutes:An.optional(),terminalCopyOnSelect:e.boolean().optional(),allowFastServiceTier:e.boolean().optional(),telemetryEnabled:e.boolean().optional(),confirmThreadArchive:e.boolean().optional(),showGitChanges:e.boolean().optional(),keepHistoryAfterContextClear:e.boolean().optional(),summarizeShellCommands:e.boolean().optional(),showUnhandledProviderEvents:e.boolean().optional(),onboardingCompletedAt:e.string().min(1).nullable().optional(),earlyAdopter:e.boolean().optional()}),yt.omit({showDiagnosticEvents:!0}).extend({idleProviderSessionTimeoutMinutes:An.optional(),terminalCopyOnSelect:e.boolean().optional(),allowFastServiceTier:e.boolean().optional(),telemetryEnabled:e.boolean().optional(),confirmThreadArchive:e.boolean().optional(),showGitChanges:e.boolean().optional(),keepHistoryAfterContextClear:e.boolean().optional(),summarizeShellCommands:e.boolean().optional(),showUnhandledProviderEvents:e.boolean(),onboardingCompletedAt:e.string().min(1).nullable().optional(),earlyAdopter:e.boolean().optional()})]);var vd=["thread.jump.1","thread.jump.2","thread.jump.3","thread.jump.4","thread.jump.5","thread.jump.6","thread.jump.7","thread.jump.8","thread.jump.9"],Sd=["question.select.1","question.select.2","question.select.3","question.select.4","question.select.5","question.select.6","question.select.7","question.select.8","question.select.9"],xd=["pane.focus.left","pane.focus.right","pane.focus.up","pane.focus.down"],Rd=["pane.focus.1","pane.focus.2","pane.focus.3","pane.focus.4","pane.focus.5","pane.focus.6","pane.focus.7","pane.focus.8"],Td=["palette.open","thread.new","thread.search","thread.rename","thread.archive","thread.previous","thread.next","history.back","history.forward",...vd,...xd,"pane.focus.previous","pane.focus.next",...Rd,"pane.maximize.toggle","pane.close","window.new","window.find","window.reload","app.back","settings.open","settings.openServers","sidebar.toggle","panel.previousTab","panel.nextTab","panel.previousNewTabItem","panel.nextNewTabItem","panel.newTab","panel.reopenClosedTab","panel.close","panel.toggle","panel.fullScreen.toggle","file.quickOpen","diff.toggle","terminal.open","composer.focus","modelPicker.toggle","modelPicker.cycleModel","modelPicker.cycleModelBackward","modelPicker.cycleProvider","modelPicker.cycleProviderBackward","modelPicker.cycleReasoning","modelPicker.cycleReasoningBackward","browser.focusLocation","browser.reload","browser.find","workspace.openPreferred","logs.openServerDaemon","dataDirectory.open","notifications.open","plugins.enterSafeMode","plugins.exitSafeMode","plugins.pruneCache",...Sd],wd=e.enum(Td),kd=e.templateLiteral(["plugin:",e.string(),"/",e.string()]).refine(n=>/^plugin:[a-z0-9][a-z0-9-]*\/[a-zA-Z0-9_-]+$/u.test(n)&&n.length<=256,"Invalid plugin command ID"),Ms=e.union([wd,kd]);var Pd=["mainSurface","modalOpen","editableFocus","terminalFocus","browserFocus","modelPickerOpen","questionOpen","promptAvailable","splitActive","webSurface","macPlatform","windowsPlatform","linuxPlatform"],_s=e.enum(Pd),In=e.object({key:e.string().min(1).max(32),mod:e.boolean(),meta:e.boolean(),control:e.boolean(),alt:e.boolean(),shift:e.boolean()}).strict();var Ad=e.enum(["mac","windows","linux"]);var Id=e.object({all:e.array(_s),none:e.array(_s)}).strict(),Ds=e.object({command:Ms,desktopOnly:e.boolean(),shortcut:In,when:Id}).strict(),Ed=Ds.extend({shortcut:In.nullable()});var Os=e.array(Ds).max(1024),Ls=e.array(Ed).max(256),Cd=e.object({command:Ms,shortcut:In.nullable(),platform:Ad.optional()}).strict(),qs=e.array(Cd).max(1024).superRefine((n,t)=>{let r=new Set;for(let[s,i]of n.entries()){let a=`${i.command}:${i.platform??"all"}`;r.has(a)&&t.addIssue({code:"custom",message:`Duplicate override for ${i.command}`,path:[s,"command"]}),r.add(a)}});var jd="pierre-dark",_d="pierre-light",vt=e.string().min(1).max(128).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/,"Code theme names may use letters, digits, '.', '_', ':', and '-' and cannot start with '.'"),dv=e.object({dark:vt,light:vt}).strict(),cv=je.refine(n=>typeof n.name=="string"&&n.name.length>0,{message:"Code theme JSON must include a non-empty name"}),Us=e.object({dark:vt,light:vt,files:e.record(e.string(),je)}).strict(),En={dark:jd,light:_d,files:{}},pv=e.object({dark:e.string().min(1).max(256).optional(),light:e.string().min(1).max(256).optional()}).strict();var Md=e.enum(["default","nord","dracula","solarized","gruvbox","catppuccin"]),gv=[{id:"default",name:"Default",description:"The standard bb look"},{id:"nord",name:"Nord",description:"Cool, muted arctic blues"},{id:"dracula",name:"Dracula",description:"Dark, high-contrast purple and pink"},{id:"solarized",name:"Solarized",description:"Balanced light and dark (Schoonover palette)"},{id:"gruvbox",name:"Gruvbox",description:"Warm retro earth tones"},{id:"catppuccin",name:"Catppuccin",description:"Soothing pastel \u2014 Latte light, Mocha dark"}],Dd=Md.options;function Od(n){return Dd.includes(n)}var fv=e.string().min(1).max(64).regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,"Custom theme names may use letters, digits, '.', '_', and '-' and cannot start with '.'").refine(n=>n!=="."&&n!=="..","Invalid custom theme name").refine(n=>!Od(n),"Custom theme name collides with a built-in palette id"),Ld=256e3,qd=["red","orange","yellow","green","teal","blue","purple","pink"],Bs=e.enum(["default",...qd]),Ud="default",Cn=e.object({themeId:e.string().min(1),customCss:e.string().max(Ld).nullable(),faviconColor:Bs,resolvedCodeTheme:Us.default(En)}),jn=e.object({id:e.string().min(1),pluginId:e.string().min(1),name:e.string().min(1),description:e.string().nullable()});var bv=e.object({themeId:e.string().min(1),faviconColor:Bs}),yv={themeId:"default",customCss:null,faviconColor:Ud,resolvedCodeTheme:En};var Bd=e.discriminatedUnion("type",[e.object({type:e.literal("existing"),hostId:e.string().min(1)}),e.object({type:e.literal("new"),machineProviderId:e.string().min(1),inputs:S.nullable()})]),zd=e.object({machine:Bd,inputs:S.nullable()}),Nd=["creating","provisioning","ready","error","destroyed"],me=e.enum(Nd),Hd=["active","removing","cleanup-failed","removed"],Fd=e.enum(Hd);var Wd=["unmanaged","managed-worktree","personal"],$d=e.enum(Wd),Qd=["managed-worktree","unmanaged-worktree","other"],zs=e.enum(Qd),Rv=e.object({path:e.string().min(1),isGitRepo:e.boolean(),isWorktree:e.boolean(),branchName:e.string().nullable(),defaultBranch:e.string().nullable()}),Gd=e.object({phase:e.enum(["active","retiring","teardown","destroyed"]),retireAt:e.number().nullable(),teardown:e.object({status:e.enum(["running","failed","removed"]),attempt:e.number().int().nonnegative(),message:e.string().optional()}).nullable()}),St=e.object({id:e.string(),name:e.string().nullable(),projectId:e.string(),hostId:e.string(),path:e.string().nullable(),isGitRepo:e.boolean(),isWorktree:e.boolean(),branchName:e.string().nullable(),baseBranch:e.string().nullable(),defaultBranch:e.string().nullable(),mergeBaseBranch:e.string().nullable(),status:me,environmentProviderId:e.string().nullable(),lifecycle:Gd,hostLifecycle:Fd,environmentProviderSelection:zd.nullable(),environmentProviderInstanceKey:e.string().nullable(),managed:e.boolean(),workspaceProvisionType:$d.nullable(),createdAt:e.number(),updatedAt:e.number()});function Tv(n){return n?.mergeBaseBranch??n?.baseBranch??n?.defaultBranch??void 0}var k=e.string().regex(/^[a-z0-9][a-z0-9-]*$/u);function Pv(n){let r=(n.includes("/")?n.split("/").at(-1)??n:n).replace(/^bb-plugin-/,"").toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"");if(r.length===0)throw new Error(`cannot derive a plugin id from package name "${n}"`);return r}var Jd=["changelogPreview","compactExpiredCache","serverMove","performanceDiagnostics","sidebarMultiSelect","timelinePush"],Ns=e.enum(Jd),Hs=e.record(Ns,e.boolean()),Ev=e.partialRecord(Ns,e.boolean());var _v="proj_personal",Kd=["standard","personal"],Vd=e.enum(Kd),Fs=e.object({id:e.string(),kind:Vd,name:e.string(),gitRemoteUrl:e.string().nullable(),createdAt:e.number(),updatedAt:e.number()}),Xd=["local_path"],Mv=e.enum(Xd),Yd=e.object({id:e.string(),projectId:e.string(),isDefault:e.boolean(),createdAt:e.number(),updatedAt:e.number()}),Zd=Yd.extend({type:e.literal("local_path"),hostId:e.string(),path:e.string()}),Ws=Zd;var ec="bb/provider-commands",tc="bb/session-options",nc=e.object({name:e.string().min(1),description:e.string(),inputHint:e.string().min(1).optional()}),rc=e.object({commands:e.array(nc).max(500)}),sc=e.object({id:e.string().min(1),label:e.string().min(1),description:e.string().min(1).optional(),group:e.string().min(1).optional()}),$s={id:e.string().min(1),label:e.string().min(1),description:e.string().min(1).optional(),category:e.string().min(1).optional()},_n=e.discriminatedUnion("type",[e.object({...$s,type:e.literal("select"),value:e.string(),values:e.array(sc).max(1e3)}),e.object({...$s,type:e.literal("boolean"),value:e.boolean(),fixed:e.boolean().optional()})]),ic=e.object({options:e.array(_n).max(64)});var qv=e.object({selections:pt});function oc(n,t){if(n.type==="boolean"&&t.type==="boolean")return n.fixed!==!0?n:t.fixed!==!0?t:n.value===t.value?n:{...n,value:!1,fixed:!1};if(n.type==="select"&&t.type==="select"){let r=new Set(n.values.map(s=>s.id));return{...n,values:[...n.values,...t.values.filter(s=>!r.has(s.id))]}}return n}function Uv(n){let t=new Map;for(let r of n)for(let s of r.sessionOptions??[]){let i=t.get(s.id);t.set(s.id,i===void 0?s:oc(i,s))}return[...t.values()].map(r=>r.type==="boolean"&&r.fixed!==void 0?{...r,fixed:!1}:r)}var Bv={[ec]:rc,[tc]:ic};var ac=500,lc=200,Mn=64*1024,dc=Math.ceil(Mn/3)*4,cc=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u,pc=["starting","running","disconnected","exited"],Dn=e.enum(pc);var uc=["user","process-exit","daemon-disconnect","environment-destroyed","thread-archived","thread-deleted","open-timeout"],On=e.enum(uc);function mc(n){let t=n.endsWith("==")?2:n.endsWith("=")?1:0;return n.length/4*3-t}var Oe=e.number().int().positive().max(ac),Le=e.number().int().positive().max(lc),xt=e.string().min(1).max(dc).regex(cc).refine(n=>mc(n)<=Mn,{message:`Terminal data must decode to ${Mn} bytes or less`});var Qs=[{id:"agentThreadMessage",body:`[bb message from thread:{{senderThreadId}}]
|
|
9
|
-
|
|
10
|
-
{{messageText}}`,variables:{senderThreadId:"The thread ID that sent the message.",messageText:"The original message text sent by the agent."}},{id:"bbGuideAgentConfiguration",body:`Agent configuration
|
|
11
|
-
|
|
12
|
-
bb reads agent configuration from the app data dir and from a project's .bb/
|
|
13
|
-
directory. These files shape how agents behave in provider-backed threads.
|
|
14
|
-
|
|
15
|
-
User instructions (<dataDir>/AGENTS.md):
|
|
16
|
-
|
|
17
|
-
Add an AGENTS.md file to the bb data dir (usually ~/.bb/AGENTS.md) to give
|
|
18
|
-
every provider-backed thread across all projects default user-level
|
|
19
|
-
instructions. bb reads <dataDir>/AGENTS.md and appends its contents to the
|
|
20
|
-
thread system prompt for all providers when a provider session starts.
|
|
21
|
-
|
|
22
|
-
Workspace instructions (.bb/AGENTS.md):
|
|
23
|
-
|
|
24
|
-
Add a .bb/AGENTS.md file to a workspace to give every thread that runs there
|
|
25
|
-
repo-specific instructions. bb reads <workspace>/.bb/AGENTS.md and appends its
|
|
26
|
-
contents to the thread system prompt for all providers, after any
|
|
27
|
-
<dataDir>/AGENTS.md instructions, when a provider session starts. Track it with
|
|
28
|
-
git so fresh managed worktrees include it.
|
|
29
|
-
|
|
30
|
-
Only the plural AGENTS.md is read, only from the exact data-dir and
|
|
31
|
-
workspace-root .bb/ locations above (bb does not walk parent directories), and
|
|
32
|
-
an empty file is ignored. This is bb's own provider-agnostic instruction
|
|
33
|
-
injection, separate from provider-native instruction files. Codex reads a
|
|
34
|
-
repo-root AGENTS.md. Claude Code 2.1.277 and later also reads AGENTS.md when
|
|
35
|
-
no project or ancestor CLAUDE.md or CLAUDE.local.md takes precedence. Older
|
|
36
|
-
Claude Code versions and sessions without its built-in AGENTS.md support
|
|
37
|
-
still require CLAUDE.md.
|
|
38
|
-
|
|
39
|
-
Skills (.bb/skills/):
|
|
40
|
-
|
|
41
|
-
A skill is a reusable instruction file that bb injects into a thread and
|
|
42
|
-
exposes to the agent as a slash command. Place project skills under
|
|
43
|
-
.bb/skills/<name>/SKILL.md in a workspace. Each SKILL.md has YAML frontmatter
|
|
44
|
-
with \`name\` (lowercase, hyphenated, matching the directory) and \`description\`,
|
|
45
|
-
followed by the instruction body.
|
|
46
|
-
|
|
47
|
-
bb resolves skills from three sources, in increasing precedence:
|
|
48
|
-
|
|
49
|
-
plugin Skills from enabled plugins, including the bundled BB guide.
|
|
50
|
-
user <dataDir>/skills (e.g. ~/.bb/skills).
|
|
51
|
-
project <workspace>/.bb/skills.
|
|
52
|
-
|
|
53
|
-
A project skill overrides a user or plugin skill with the same name. Two
|
|
54
|
-
skills with the same name within one source collide and are both dropped.
|
|
55
|
-
|
|
56
|
-
User skill roots, directories, and SKILL.md entries may be symlinks. Project
|
|
57
|
-
skill and command links must stay within the workspace or repository boundary.
|
|
58
|
-
Supporting files inside injected skill trees must be ordinary files/directories.
|
|
59
|
-
Listings collapse skills that share a name and identical SKILL.md content
|
|
60
|
-
across roots; different content or a different name stays distinct. Existing IDs still address the original
|
|
61
|
-
registration. Linked registrations are read-only. Codex receives a selected
|
|
62
|
-
skill as a structured name/path input, including when steering an active turn.
|
|
63
|
-
|
|
64
|
-
Use \`bb skill list\` to inspect installed and discovered skills and copy the
|
|
65
|
-
opaque skill ID. \`bb skill show|files <skill-id>\` reads that exact skill;
|
|
66
|
-
\`bb skill show <skill-id> --json\` returns the revision required by \`bb skill
|
|
67
|
-
update <skill-id> --revision <sha256>\`. \`bb skill delete <skill-id>\` and
|
|
68
|
-
update are restricted to editable, user-owned skills. These workspace-scoped
|
|
69
|
-
commands default to \`BB_PROJECT_ID\`, then the personal project; pass
|
|
70
|
-
\`--project\` or \`--environment\` when a different workspace is required.
|
|
71
|
-
|
|
72
|
-
Use \`bb skill search [query]\` to browse skills.sh (no query lists what is
|
|
73
|
-
trending; \`--page\` starts at 0 and \`--per-page\` defaults to 24). JSON
|
|
74
|
-
\`installs\` counts the \`ranking\` window; \`lifetimeInstalls\` may be null. Use \`bb skill registry detail
|
|
75
|
-
<registry-skill-id>\` to inspect metadata and the bounded file preview, and
|
|
76
|
-
\`bb skill install <registry-skill-id>\` to install that canonical registry
|
|
77
|
-
identity into bb user skills. Registry commands are server-wide and do not
|
|
78
|
-
accept workspace selectors.
|
|
79
|
-
|
|
80
|
-
Use \`bb skill install-cli-skills\` to copy bb's built-in CLI skills into a
|
|
81
|
-
machine's global agent skill roots (\`~/.agents/skills\` and
|
|
82
|
-
\`~/.claude/skills\`) so agents running outside bb can drive it. It installs on
|
|
83
|
-
every connected persistent machine unless you pass \`--machine <id-or-name>\`
|
|
84
|
-
(repeatable; required for a sandbox) (Settings \u2192 Skills has the same action). Machines install
|
|
85
|
-
independently, so the command reports each machine's outcome and exits
|
|
86
|
-
non-zero if any failed. The install replaces a previously installed copy of
|
|
87
|
-
the same skill and leaves other skills alone. \`bb skill cli-skills-status\`
|
|
88
|
-
reports whether each machine is installed, out of date, missing, or unknown
|
|
89
|
-
(disconnected or unreachable).
|
|
90
|
-
|
|
91
|
-
Use the skill-creator skill to author and iterate on skills.
|
|
92
|
-
|
|
93
|
-
BB guide plugin:
|
|
94
|
-
|
|
95
|
-
The enabled-by-default BB guide plugin owns the BB introduction and the
|
|
96
|
-
bb-cli, bb-plugin-authoring, skill-creator, and submit-a-plugin skills. Settings \u2192 Installed
|
|
97
|
-
plugins \u2192 BB guide exposes introduction, a master skills switch, and one
|
|
98
|
-
switch per skill. All default to true. Use:
|
|
99
|
-
|
|
100
|
-
bb plugin config bb-guide set introduction false
|
|
101
|
-
bb plugin config bb-guide set skills false
|
|
102
|
-
bb plugin config bb-guide set bbCli false
|
|
103
|
-
bb plugin config bb-guide set pluginAuthoring false
|
|
104
|
-
bb plugin config bb-guide set skillCreator false
|
|
105
|
-
bb plugin config bb-guide set submitPlugin false
|
|
106
|
-
|
|
107
|
-
Changes apply when agent configuration is next assembled. They do not erase
|
|
108
|
-
existing conversation text or disable independently installed copies.`,variables:{}},{id:"bbGuideBrowser",body:"# Built-in browser automation\n\n`bb browser` is the experimental core API for automation integrations controlling BB desktop tabs. The bundled Browser Automation plugin adds its own `bb browser-automation` session commands (see its browser-automation skill); another plugin can use the same core connection independently.\n\nStart with `bb browser instances --host <host-id> --json`. For every tab/control operation provide `--host <host-id> --instance <instance-id> --generation <generation> --thread <thread-id>`. The browser host can differ from the agent host. Never infer an active desktop window.\n\n- `tabs`: list native tabs and their control state.\n- `create [--url <http(s)-url>] [--reveal]`: create a tab in the BB browser profile, with the user's signed-in cookies. Defaults: hidden, about:blank.\n- `acquire <tab-ids...> --controller <label> [--ttl-ms <ms>]`: acquire exclusive tab control. It reveals the first tab only when the owning thread is already focused; it never switches threads or activates a desktop window. Default expiry is five minutes, maximum thirty minutes. Controlled tabs carry the BB browser profile's signed-in authority.\n- `connection <lease-id> --output <new-file>`: write private connection JSON with mode 0600 on the CLI host. The loopback WebSocket endpoint is usable only on the browser host. Pass it privately to an integration worker; never expose it through a shared port or chat output.\n- `release <lease-id>`: revoke automation while keeping tabs open.\n- `reveal <tab-id>`: open the side panel and select the existing native tab only if its thread is already focused; otherwise leave the current view unchanged.\n- `capture <tab-id> --output <new-file>`: save a bounded JPEG to the CLI host without focusing the tab.\n- `close <tab-id>`: explicitly close that native tab.\n- `watch`: print changed tab snapshots every two seconds until interrupted. Disconnects report errors; this is not a lossless event log.\n\nCookie import copies signed-in sessions from a browser installed on the desktop host into the BB browser profile. These two commands take `--host`, `--instance`, and `--generation` but no `--thread`:\n\n- `import-sources`: combine known-browser entries (Chrome, Chromium, Helium (macOS), Edge, Brave, Vivaldi, Opera, Arc (macOS), Dia (macOS), Firefox, Zen, Safari (macOS)) with automatically detected Chromium/Firefox cookie stores, their profiles with cookie counts, and why one is unavailable (`notInstalled`, `browserRunning`, `needsFullDiskAccess`, `needsKeychainApproval`, `unsupportedPlatform`).\n- `import-cookies --from <source-id> --profile <directory>`: read that profile's cookie store and write it into the BB browser profile. The source browser must be quit first. macOS prompts for Keychain access for Chromium browsers and needs Full Disk Access for Safari. The result reports imported and skipped counts plus skipped hosts; `ok: false` carries a reason. A one-time copy, never a sync; partitioned cookies and non-default Firefox containers are skipped. Desktop only (macOS and Linux). Use the exact source ID returned by `import-sources`; additional stores have stable opaque `storage-\u2026` IDs.\n\nDiscovery finds known browsers plus other Chromium and Firefox cookie stores in standard per-user locations, including Flatpak and Snap; it reads no encryption secrets and excludes BB's own desktop profile. Arbitrary custom locations, other cookie formats, and custom encryption are not supported. Refresh rescans.\n\nAll commands support JSON output. In plugin code use `bb.sdk.experimental_desktopBrowsers`; the Plugin Guide documents the typed surface. Stop/Take over revokes native control; stopping the owning thread also releases its server control leases. Old connection generations cannot control replacement windows.\n\nCloud browsers are not supported. Headless Chrome on an enrolled host belongs to the Browser Automation plugin.",variables:{}},{id:"bbGuideCustomization",body:"Customization commands\n\nBundled plugins such as Keep Awake, Concurrency limit, Thread list, and Push\nnotifications own their settings and commands; run `bb guide plugins`.\n\nTheming \u2014 the app-wide palette and typography\n\n`bb theme` controls a set of CSS-variable overrides for the app palette and\ntypography, persisted server-side and applied live to every open window.\nLight/dark mode is a separate per-client setting the theme layers on top of.\nCustom themes live on\ndisk, one folder per theme, at <bb-data-dir>/theme/<name>/theme.css (the packaged\napp uses ~/.bb/theme/\u2026). The folder name is the theme id.\n\nbb theme list Built-in and custom themes; shows the active one\nbb theme dir Print the custom-theme directory (where to author)\nbb theme set <id> [--favicon-color <color>]\nActivate a theme (built-ins: default, nord,\ndracula, solarized, gruvbox, catppuccin),\npreserving the favicon color unless the flag\nsupplies the complete selection\nbb theme show [id] [--css] Print the active palette, or resolve <id> without\nactivating it; --css dumps the CSS\nbb theme reset Back to the default theme; preserve favicon color\nbb theme favicon set <color> Set favicon color; preserve the active theme\nbb theme favicon reset Reset favicon color; preserve the active theme\n\nTo author a custom theme, run `bb theme dir`, write <that-dir>/<name>/theme.css,\nthen `bb theme set <name>`. A name has at most 64 characters, starts with a\nletter or digit, then uses letters, digits, `.`, `_`, or `-`; avoid built-in\nids. Optional `pierre-dark.json` / `pierre-light.json`\n(or a `theme.json` `codeTheme` field) ship the matching code colors. Built-in\npalettes use the matching Shiki pair. The full design-token reference is in\nthe bb-cli skill (references/theming.md).\n\nTheme CSS can override typography as well as colors. `--font-terminal` controls\nthe integrated terminal's font family independently of `--font-mono`; set it in\nthe theme's `:root, .light` block and end the stack with a generic fallback.\n\nFavicon colors are `default`, `red`, `orange`, `yellow`, `green`, `teal`,\n`blue`, `purple`, and `pink`. Theme and favicon-only commands carry the other\nappearance value forward explicitly.\n\nHovering a palette in Settings \u2192 Appearance previews it live in that window\nwithout saving; `bb theme show <id>` is the CLI counterpart.\n\nAdd --json to any theme command for machine-readable output.\n\nServer-backed settings\n\nSettings stored server-side apply to every window and survive restarts.\n\nbb settings show\nbb settings ai-services\nbb settings ai-services set <thread-title|commit-message|voice> <automatic|off|service-id> [--plugin <plugin-id>]\nbb settings ai-services test <thread-title|commit-message>\nbb settings general <key> <value>\nbb settings replay-onboarding\nbb settings completed-turns [provider-id] [collapse|flat|default]\nbb settings experiment <key> <value>\nbb settings usage [--machine <id-or-name>] [--refresh]\nbb settings cli-command [install|remove]\nbb settings version [--force]\nbb settings reload Reload bb-managed configuration\n\nAI services: `bb settings ai-services` shows which AI service writes thread\ntitles (and so branch names), commit messages, and voice transcripts, plus\nevery service a plugin registers and whether it is ready. `set` picks\n`automatic` (bb cloud first, then all other compatible services by plugin id\nand service id in lexicographic order, including third-party plugins), `off`,\nor one service id; a picked service is never swapped for another. A service is\nidentified by its plugin and its id, so two plugins may use the same id; pass\n`--plugin <plugin-id>` when they do. `test` runs a sample title or commit\nmessage through the current choice. Settings \u2192 AI services has the same\ncontrols. Each plugin chooses its own model. The removed `BB_INFERENCE`,\n`BB_INFERENCE_FALLBACK`, and `BB_TRANSCRIPTION` variables are ignored with a\nwarning in `~/.bb/config.json`, and `bb-app config set` refuses them.\n\nGeneral keys: `bb settings general` accepts any key from `generalSettings` in\n`bb settings show`; an unknown key or wrongly shaped value is rejected with the\nlist of known keys. Boolean preferences take `true`, `false`, `on`, or `off`,\nand `null` clears a preference that can be unset. Most appear in Settings \u2192\nGeneral. Machine-related keys (`machineServerUrl`, `defaultMachineAccess`,\n`machineGitCredentialsEnabled`) are covered in `bb guide machines`.\n\n- `showDiagnosticEvents` (default false) shows provider environment resolution\n and unhandled provider events in the timeline. Warnings, errors, and model\n fallback stay visible either way.\n- `steerActiveThreadOnEnter` (default true for a new install; an earlier\n install with saved settings or work keeps false): when on, Enter steers a\n running thread and Command+Enter queues a follow-up; when off, those are\n reversed. Shift+Enter inserts a newline.\n- `showGitChanges` (default true; Settings \u2192 General \u2192 Show Git changes and\n Commit button): false hides the git summary, expanded file list,\n pull-request status and actions above the composer, and Commit action in the\n thread header and overflow menu for every thread and connected client. Thread\n relationships and workspace warnings remain visible.\n- `keepHistoryAfterContextClear` (default false; Settings \u2192 General \u2192 Show\n messages from before a context clear): true keeps a cleared thread's earlier\n messages above the `Context cleared` boundary in the timeline, outline, and\n message lookups. The next prompt still starts a fresh provider conversation,\n and the context meter still resets.\n- `summarizeShellCommands` (default true; Settings \u2192 General \u2192 Summarize shell\n commands): false stops titling shell commands that read, list, or search files\n with a summary such as `Searched for X`. Each command row then shows its\n command and expands to the command and its output.\n- `confirmThreadArchive` (default true): set false to archive parent and child\n threads in the app without the confirmation popup; the toast still offers\n Undo. CLI and SDK archive calls are always non-interactive.\n- `terminalCopyOnSelect` (default true; Settings \u2192 General \u2192 Terminals \u2192 Copy\n on select) copies completed terminal selections exactly and shows \"Selection\n copied\". Text elsewhere in the app is unchanged. Set it with\n `bb settings general terminalCopyOnSelect <true|false|on|off>` or SDK\n `system.updateGeneralSettings`. Explicit Copy/Paste work when off. Supported\n Linux browsers use native primary selection for middle-click paste,\n independently of this preference, never the regular clipboard as a fallback.\n- `streamerMode` (default false) hides every `customModels` entry from\n `~/.bb/config.json` in all model lists (pickers, `bb provider models`, and\n the SDK) during a screen share. The entries stay in the config file; a\n request that names a hidden model still runs with it, and default model\n resolution still sees the full list.\n- `allowFastServiceTier` (default true; Settings \u2192 Providers): false hides the\n service tier control and runs new turns at the default service tier,\n including explicit requests for any other tier (fast, Codex ultrafast), saved\n project defaults, automations, and messages queued before the change. Project\n defaults saved while it was off retain the default tier.\n- `managedBranchPrefix` (default `bb/`, at most 64 characters) prefixes every\n branch bb creates for a worktree or a new checkout branch: the default gives\n `bb/fix-login-flow-thr_ab12cd34ef`, `sawyer/wt-` gives\n `sawyer/wt-fix-login-flow-thr_ab12cd34ef`, and an empty value gives no\n prefix. bb rejects a prefix that cannot start a valid git branch name.\n Existing branches keep their names.\n- `providerOrder` (default `[]`) is a JSON array of provider ids, and\n `defaultProviderId` (default `null`) names the default provider; `null`\n clears it.\n- `idleProviderSessionTimeoutMinutes` (default `30`; Settings \u2192 Providers \u2192 Configuration \u2192 Release idle agent sessions) sets how long an agent can sit idle after its last turn before every machine stops its provider process. Allowed values are `0` (ASAP), `5`, `10`, `30`, and `60`, for example `bb settings general idleProviderSessionTimeoutMinutes 5`. Machines check every five minutes, so release can take up to five minutes beyond the timeout. Changes apply live and on reconnect. Only restorable sessions without active or pending work are eligible; threads keep their history and resume on the next message. `bb thread stop` still releases a runtime manually. This is not a limit on loaded processes or memory. Read the value with `bb settings show`; SDK callers use `system.config()` and `system.updateGeneralSettings({ ...config.generalSettings, idleProviderSessionTimeoutMinutes: 5 })`.\n- `telemetryEnabled`: see Telemetry below.\n\n`bb settings replay-onboarding` clears `onboardingCompletedAt`, so the\nfirst-run setup guide (connect an agent, add projects, pick plugins, set up\ndevices) shows again in every open client. Settings \u2192 General \u2192 Setup guide has\nthe same button.\n\n`bb settings usage --refresh` fetches fresh provider usage; ordinary reads may\nreuse results for 10 seconds. The SDK equivalent is\n`bb.sdk.system.usageLimits({ refresh: true })`.\n\nCommand line: Settings \u2192 General \u2192 Command line puts the `bb` command on PATH\non the computer that runs the bb server, so the user, a script, or an agent\nrunning outside bb (such as Claude Code or Codex) can control bb; threads in bb\nalready have `bb`. `bb settings cli-command` shows the state, and `install` or\n`remove` changes it. Install links the launcher at `~/.bb/bin/bb` into a PATH\nfolder such as `~/.local/bin` (on Windows it adds `~/.bb/bin` to the user\nPATH). bb never replaces another `bb`: install is refused while one runs first\nin a new terminal. Only an installed bb (`npx bb-app` or the desktop app)\noffers this; a source checkout does not.\n\nCompleted turns: `bb settings completed-turns` lists how each provider shows a\nfinished turn: `collapse` folds the turn's work into one \"Worked for\" row and\nkeeps the final answer visible, and `flat` keeps every step visible. Each\nprovider has a default (Claude Code is `flat`, the other first-party providers\n`collapse`); `--json` shows whether each value comes from your setting or that\ndefault. `bb settings completed-turns <provider-id> <collapse|flat>` overrides\nit for that provider, and `default` removes the override. It applies to\nexisting threads too, including `bb thread log`. Settings \u2192 Providers has the\nsame per-provider switch.\n\nExperiments: `bb settings experiment <key> <true|false>` toggles a default-off\nexperiment (Settings \u2192 Experiments). `changelogPreview` shows the latest\nrelease notes as a dismissible card on Settings \u2192 Updates. Experiments that\ngate a feature are documented with it: `serverMove` in `bb guide machines`,\n`performanceDiagnostics` under Server performance diagnostics below.\n`timelinePush` sends an open thread's timeline updates over the live\nconnection as row deltas instead of reloading the latest window after each\nupdate. `compactExpiredCache` offers a Compact chip in the composer when an idle\nthread's prompt cache has expired and its context holds at least 100k tokens;\nsee `bb guide thread-messaging` for `--compact-first`.\n`sidebarMultiSelect` lets the built-in thread list sidebar select several threads with\nCmd/Ctrl-click and Shift-click for bulk actions and drag; while it is off,\nCmd/Ctrl-click opens a thread in a split.\n`bb settings general earlyAdopter on` (Settings \u2192 Experiments \u2192 Become an early\nadopter) turns on the experiments marked Early adopter, currently\n`timelinePush`, `compactExpiredCache`, and `sidebarMultiSelect`; an experiment you set yourself keeps\nyour value.\n\nLauncher settings\n\n`bb-app config` and `bb-app env` reload runtime settings in a running server,\nbut the CLI identifies settings that are startup-only, including binding/ports,\ndata and the dev-app port, telemetry, inherited skill roots, and\n`BB_LOG_LEVEL`. Use `bb-app config`, not `bb-app env`, to change `BB_APP_URL`\nlive. After a startup-only change, run `bb-app stop && bb-app start` or restart\nthe desktop app; until then, changing or unsetting `BB_SERVER_BIND_HOST` does\nnot close a previous `0.0.0.0` listener.\n\n`--server-bind-host 0.0.0.0` (or `BB_SERVER_BIND_HOST=0.0.0.0`) listens on\nevery interface for direct remote access; containers must also publish the\nport. BB accepts request hosts that are `localhost`, IP addresses (including\nLAN and Tailscale IPs), or the hostname in `BB_APP_URL`. For a custom DNS name\nor reverse proxy, run `npx bb-app config set BB_APP_URL https://bb.example.com`\nbefore connecting, including from the CLI or SDK; forwarded host headers cannot\nauthorize an unconfigured name. BB Connect needs no additional configuration.\n\nKeyboard shortcuts\n\nSettings \u2192 Keyboard records per-command shortcut overrides, persisted\nserver-side and applied live to every connected window, including desktop menu\naccelerators. Reset removes an override and returns to bb's current default;\n`disabled` explicitly unbinds a command. `Mod` means Command on macOS and\nControl on Windows/Linux. The complete default table is in docs/configuration.md.\n\nbb settings keyboard list\nbb settings keyboard hints <true|false>\nbb settings keyboard set <command> <shortcut|disabled> [--platform mac|windows|linux]\nbb settings keyboard reset [command] [--platform mac|windows|linux]\n\n`keyboard list` prints core command ids with their effective bindings, plus\nevery saved override; examples include `panel.previousTab` / `panel.nextTab`,\n`pane.focus.left|right|up|down`, `pane.maximize.toggle`, and the initially\nunbound `panel.fullScreen.toggle`. `hints` (default true) shows or hides the\ndelayed shortcut badges shown while holding the modifier key; shortcuts work\neither way.\n\n`history.back` / `history.forward` (`Mod+[` / `Mod+]`) follow the pages opened\nin the current window, like the sidebar arrows. `thread.previous` /\n`thread.next` follow sidebar order instead: `Mod+Shift+[` / `Mod+Shift+]`\non desktop and `Control+Shift+[` / `Control+Shift+]` on the web.\n\nAn override can be scoped with `--platform`; without it, it applies on all\nplatforms. A platform-specific override takes precedence over a general one,\nincluding when disabled. Scoped `set` and `reset` keep other platforms'\noverrides; unscoped `set` updates the general override, and unscoped `reset`\nclears every scope for the command (or every command if omitted). The SDK uses\n`system.updateKeyboardSettings` to write and `system.config` to read bindings.\n\nPlugin commands use `plugin:<plugin-id>/<command-id>` as their binding ID, for\nexample `bb settings keyboard set plugin:example/open-issue Mod+Shift+I`;\n`reset` restores the plugin's default. Overrides survive plugin disable,\nre-enable, and reload. Commands without defaults start unbound, and\nconflicting plugin defaults stay unbound. Plugin defaults resolve in each app\nwindow, not in `keyboard list`, so CLI/SDK callers should clear conflicting\nexplicit bindings in the same update.\n\nSidebar preferences\n\n`bb settings ui` reads and writes server-side sidebar preferences shared by\nevery window, device, and the CLI. The same registry stores which thread Info\npanel sections are collapsed (`infoPanel.collapsedSections`).\n\nbb settings ui list [--json]\nbb settings ui get <key> [--json]\nbb settings ui set <key> <value> [--json]\nbb settings ui reset <key> [--json]\n\n`list` prints every key with its value, revision, and a short description.\n`set` takes plain strings for enum and provider keys and JSON for lists and\n`null`; it retries once if another writer changed the key. `reset` writes the\ndefault. The SDK offers `sdk.system.uiPreferences.list()`, `.set()`, and\n`.reset()`.\n\nThe thread list is drawn by `sidebar.threadListProvider`, which defaults to\n`__automatic__`: the first installed thread list plugin other than the bundled\nThread list plugin (`thread-list/thread-list`), or the bundled plugin when\nthere is none, so installing a thread list plugin switches to it. Select one\nwith `bb settings ui set sidebar.threadListProvider <plugin-id>/<slot-id>`, or\nreset to restore Automatic. The bundled Thread list plugin keeps its own\nlayout (organization mode, sort, grouping, hidden and collapsed groups) and\ncopies the legacy `sidebar.*` layout keys from here only once; change its\nlayout with `bb thread-list prefs` (see `bb guide plugins`).\n\nThe composer's input box is drawn by `composer.provider`, which defaults to\n`__automatic__`: the first composer plugin you installed, or the bundled\nComposer plugin (`bb--composer/composer`) when there is none. Pick one with\n`bb settings ui set composer.provider <plugin-id>/<slot-id>`, or reset to\nrestore Automatic. With no composer plugin enabled, no composer is shown.\n\nA vertical rail of destinations sits on the left edge of the sidebar on every\nscreen size. Home is at the top and returns to the last thread; the visible\ndestinations (Plugins, Skills, and plugin panels) follow; More holds hidden\ndestinations and Customize navigation; Settings is at the bottom. New thread sits in\nthe sidebar header and cannot be hidden from the rail. The list beside the rail swaps between\nthe thread list, Plugins, Skills, and Settings, and collapsing the sidebar\nhides that list and leaves the rail. Rail order and visibility are\n`sidebar.pluginPanelOrder` and `sidebar.visiblePluginPanels`. In the macOS\ndesktop app, wide windows add a title bar holding the window controls, Back\nand Forward, and the sidebar toggle; the sidebar and page sit in a card below\nit. On narrow windows and phones the rail sits inside the drawer: Home,\nPlugins, Skills, and Settings swap the list beside it and leave the drawer\nopen, and a plugin page closes it.\n\nThe rail and the top list below are the two layouts of the bundled Navigation\nplugin, a built-in you can fork like the thread list.\n`sidebar.navigationProvider` picks what draws the navigation:\n`navigation/rail` (the rail above), `navigation/top-list` (labeled rows above\nthe thread list), another navigation plugin as `<plugin-id>/<slot-id>`, or\n`__automatic__` (the default: the first navigation from another plugin, else\n`navigation/rail`). Pick one in Settings \u2192 Appearance \u2192 Navigation, or:\n\nbb settings ui set sidebar.navigationProvider navigation/top-list\nbb settings ui reset sidebar.navigationProvider\n\nThe top list puts the visible destinations, New thread among them, and More\nabove the thread list, moves Settings into the footer, and adds a Back to app\nrow to the Settings, Plugins, and Skills lists. New thread can be reordered\nand hidden like any other row there. Collapsing hides the whole sidebar, and\nthe macOS desktop app drops the separate title bar. A navigation plugin\ndeclares whether it draws a rail or a list, and gets the matching layout; a\nlist navigation can also bring its own controls beside the sidebar toggle.\nThe same order and visibility keys apply to every provider.\n\nFooter actions: `sidebar.footerOrder` and `sidebar.hiddenFooterItems` are\nstring lists of `builtin:settings` (top list only), `builtin:mobile`,\n`builtin:report-bug`, or\n`plugin:<encoded pluginId>/<encoded registrationId>`. They survive plugin\nreloads and temporarily unavailable plugins; new items are visible by default.\n\nbb settings ui set sidebar.hiddenFooterItems '[\"plugin:bb--provider-usage/usage\"]'\nbb settings ui reset sidebar.hiddenFooterItems\n\nIn the app, the sidebar footer's More menu holds hidden actions and actions\nthat don't fit; Settings \u2192 Appearance \u2192 Sidebar footer, or right-clicking an\naction, edits the footer.\n\nThe command palette's thread search has its own Active/Archived filter, which\nis browser-local: it is not a server setting or a CLI/SDK option. The sidebar\nthread list's Active/Archived filter is the Thread list plugin's\n`threadLifecycles` preference.\n\nSidebar width and open state are per window and stay local to the browser.\n\nHost files and voice transcription\n\nbb file read|write|list|paths|mkdir|move|remove ...\nbb voice transcribe <audio-file> [--type <mime>] [--prompt <context>]\n--type defaults to audio/webm\n\n`bb file` supports `--host` for remote machines and `--root` on mutating\ncommands to confine access beneath an absolute directory. `bb file write`\ntakes exactly one of `--content` or `--stdin`; `bb file paths` lists files and\ndirectories unless `--files` or `--directories` narrows it. `bb file list` and\n`bb file paths` include dot-prefixed entries; pass `--no-hidden` to skip them.\nBoth skip a default set of dependency and cache directories such as\n`node_modules`, `.venv`, `.pnpm-store`, and root-relative `.claude/worktrees`;\n`--exclude <names...>` replaces that set. Entries match basenames at any depth\nor exact root-relative paths using `/` separators. Use\n`--json` for metadata and machine-readable results.\n\n`bb file remove` needs `--yes` without a terminal. `bb file remove --recursive`\nand `sdk.files.remove({ recursive: true, ... })` first stop processes whose\nworking directory is inside the directory, including dev servers in nested\ncheckouts (macOS and Linux only).\n\nVoice transcription uses the Voice input service chosen with\n`bb settings ai-services set voice <automatic|off|service-id>`. bb accepts\nrecordings up to 25 MB, and each service may set a lower limit; Codex takes up\nto 20 MB. These limits apply to the app, SDK, and CLI. The app's microphone\nchoice is per browser and has no `bb` command. Right-click the composer\nmicrophone, press Shift+F10, or click the Microphone control in Settings \u2192\nVoice Input to open preferences in a desktop popover or mobile drawer.\nOpening starts a local waveform preview; closing releases it. Recording\ncontrols contain cancel, stop, and send; preferences are available while idle.\n\nMissing or unreadable inputs fall back to the system default, then other\navailable inputs. Permission denials do not trigger fallback. A disconnect\nswitches inputs in the same recorder, preserving captured audio. A reconnected\npreferred device is used on the next recording. A missing preference alone\nshows no warning. Capture failures warn on the idle microphone; five seconds\nof near-silent audio warns in the preview or recording row without switching\ninputs or stopping capture. Preview audio is never saved or transcribed.\n\nTelemetry\n\nAnonymous usage telemetry is off by default and has no destination by default.\nIt sends only when all three are on: `BB_POSTHOG_API_KEY` is set and\n`BB_TELEMETRY=true` (both read at startup, for example through `bb-app env`),\nand the saved preference is on: Settings \u2192 General \u2192 Privacy & diagnostics,\n`bb settings general telemetryEnabled true`, or SDK\n`system.updateGeneralSettings` with `telemetryEnabled`. The saved preference\ntakes effect immediately. `BB_TELEMETRY=false` always disables telemetry, even\nwhen the saved preference is enabled.\n\nMobile app downloads\n\nSettings \u2192 Mobile links the iOS TestFlight\n(https://testflight.apple.com/join/T9MayTMb) and the Android APK from the\npublic `get-bb/bb` GitHub `android-testing` release (`bb-android.apk`), and\npairs either app through Add mobile device. `bb settings mobile-app --json` or\nSDK `system.mobileAppDownloads()` returns both links. Add `--details --json`\nor call `system.mobileAppReleases()` for the Android version, build, size, and\nupload date; `android` is `null` when that metadata is unavailable, and the\nlinks still work. Inside the Android app, this page compares the installed\nnative build number with the published APK. Older apps without build reporting\ncannot determine update status. Installed version and build are device-local;\nCLI and SDK metadata report the published APK.\n\nServer performance diagnostics\n\nStart with `bb-app --perf-diagnostics` or `BB_PERF_DIAGNOSTICS=1` (restart to\nchange), then run `bb settings experiment performanceDiagnostics true|false`.\nCollection needs both; it adds overhead and writes CPU profiles every 30 seconds\nto `$BB_DATA_DIR/logs/performance/` (kept 12 hours), which contain local paths.\nOpen a `.cpuprofile` in Chrome DevTools.\n\nDesktop Settings \u2192 Server \u2192 **Show This Mac** (or **Show This Computer** off macOS)\ndefaults to checked and is disabled while This Mac/Computer is selected.\nUnchecking hides the built-in server from server choices\nwhile another server is active and alternatives exist. It stays listed when\nactive or when it is the only choice. This setting does not stop the local\nruntime or change the active server.\n\nThe desktop stores `showBuiltinServer: false` in `<userData>/server-target.json`;\nmissing means shown, and saving the default omits the field. Other top-level\nmetadata is preserved. This is a desktop-local preference, with no server\nsettings CLI/SDK endpoint. Builds with tolerant readers ignore the field and\nmay drop it on save; older strict readers can reject the whole file, so keep a\nbackup before rolling back to a build predating the tolerant-reader fix #5286.",variables:{}},{id:"bbGuideEnvironments",body:`Environment commands
|
|
109
|
-
|
|
110
|
-
Environments determine where threads run. Multiple threads can share an environment
|
|
111
|
-
(e.g., a coding thread and a review thread in the same worktree).
|
|
112
|
-
The first-party choices are Project checkout (the project's existing directory),
|
|
113
|
-
Worktree (a fresh Git worktree), and Personal workspace (a projectless workspace).
|
|
114
|
-
|
|
115
|
-
New Worktree branches start at the selected base without an upstream, regardless
|
|
116
|
-
of Git's branch.autoSetupMerge setting. Publish with \`git push -u origin HEAD\`
|
|
117
|
-
to track the task's remote branch. Existing branches keep their upstream.
|
|
118
|
-
|
|
119
|
-
Making your repo work with bb:
|
|
120
|
-
|
|
121
|
-
If the default environment plugin is disabled or missing, creation fails
|
|
122
|
-
before inserting a thread. Enable the plugin or explicitly choose another
|
|
123
|
-
environment; BB does not silently replace an isolated worktree with a checkout.
|
|
124
|
-
Host-dependent preflight checks require the selected machine to be connected.
|
|
125
|
-
|
|
126
|
-
Commit a .bb-env-setup.sh script at the repo root when new bb worktrees need
|
|
127
|
-
repo-specific setup. After bb creates a new managed worktree environment, it
|
|
128
|
-
looks for .bb-env-setup.sh inside that new workspace. If the file is absent,
|
|
129
|
-
provisioning continues with no error.
|
|
130
|
-
|
|
131
|
-
The script must be tracked by git. A fresh worktree only checks out tracked
|
|
132
|
-
files, so an untracked .bb-env-setup.sh in your source checkout will not be
|
|
133
|
-
present and will not run.
|
|
134
|
-
|
|
135
|
-
BB runs the hook as \`env bash .bb-env-setup.sh\` with cwd set to the new
|
|
136
|
-
workspace. On Windows it runs the script with the bash that Git for Windows
|
|
137
|
-
installs, so the same script works there; without Git for Windows the hook
|
|
138
|
-
fails with a message naming it. The hook
|
|
139
|
-
inherits the host daemon's sanitized environment: NODE_ENV and every BB_*
|
|
140
|
-
variable are removed, and bb does not inject BB_PROJECT_ID, BB_ENVIRONMENT_ID,
|
|
141
|
-
or BB_SOURCE_PATH.
|
|
142
|
-
|
|
143
|
-
Hooks run only in paths bb created and owns, such as new worktrees and
|
|
144
|
-
checkouts bb cloned; attached project checkouts and personal workspaces never
|
|
145
|
-
run hooks. A server restart does not interrupt a running hook, but a daemon
|
|
146
|
-
restart leaves its outcome unknown.
|
|
147
|
-
|
|
148
|
-
A non-zero exit, timeout (15 minutes), signal, or cancellation fails provisioning and bb
|
|
149
|
-
removes the new worktree after confirming the script has stopped. An unknown
|
|
150
|
-
hook outcome blocks automatic cleanup and requires inspection before recovery.
|
|
151
|
-
Keep optional setup steps non-fatal inside the
|
|
152
|
-
script if the environment should still open. Provisioning progress reports
|
|
153
|
-
"Running .bb-env-setup.sh" and then ".bb-env-setup.sh finished",
|
|
154
|
-
".bb-env-setup.sh failed", or ".bb-env-setup.sh cancelled".
|
|
155
|
-
|
|
156
|
-
Commit a .bb-env-teardown.sh script at the repo root when setup creates
|
|
157
|
-
resources outside the managed worktree. BB runs the hook as
|
|
158
|
-
\`env bash .bb-env-teardown.sh\` from the worktree before it removes the
|
|
159
|
-
worktree. The hook receives the same sanitized environment as the setup
|
|
160
|
-
hook, and stdin is closed.
|
|
161
|
-
|
|
162
|
-
Teardown has a separate 15-minute timeout. A non-zero exit, timeout, or
|
|
163
|
-
signal reports failure in the destroy transcript, but bb still removes the
|
|
164
|
-
worktree once the script has stopped. An unreachable daemon leaves cleanup
|
|
165
|
-
pending for retry; a hook whose outcome is unknown blocks cleanup with an
|
|
166
|
-
explicit error.
|
|
167
|
-
|
|
168
|
-
New worktrees do not contain untracked files such as .env.local. To copy
|
|
169
|
-
them from the source checkout, commit a .worktreeinclude file at the repo
|
|
170
|
-
root. It uses gitignore syntax: one pattern per line, # for comments, ! to
|
|
171
|
-
negate an earlier pattern. bb copies each untracked file in the source
|
|
172
|
-
checkout that matches a pattern:
|
|
173
|
-
|
|
174
|
-
.env
|
|
175
|
-
.env.*
|
|
176
|
-
!.env.example
|
|
177
|
-
certs/
|
|
178
|
-
|
|
179
|
-
bb copies files only. It follows no symlinks, and it replaces nothing that
|
|
180
|
-
the worktree already has. The copy runs after \`git worktree add\` and before
|
|
181
|
-
.bb-env-setup.sh, so the setup script can read the copied files. A pattern
|
|
182
|
-
that matches nothing, or a file bb cannot read, is reported in the
|
|
183
|
-
provisioning transcript and does not fail provisioning.
|
|
184
|
-
|
|
185
|
-
Large directories such as node_modules are copied file by file. Install
|
|
186
|
-
dependencies in .bb-env-setup.sh instead of listing them here.
|
|
187
|
-
|
|
188
|
-
For files that customize agent instructions and skills (AGENTS.md,
|
|
189
|
-
.bb/AGENTS.md, .bb/skills/), run \`bb guide agent-configuration\`.
|
|
190
|
-
|
|
191
|
-
bb environment providers List registered environment providers in picker order:
|
|
192
|
-
Project checkout, Worktree, then other installed providers
|
|
193
|
-
by display name; includes id, name, the \`requires\` facts (host,
|
|
194
|
-
projectCheckout, gitCheckout, gitRemote, projectless), and whether
|
|
195
|
-
it takes --environment-inputs (--json prints the JSON Schema,
|
|
196
|
-
description, icon, and availability)
|
|
197
|
-
--project <id> Filter by structural eligibility for this project
|
|
198
|
-
--machine <id-or-name> Scope structural eligibility to this machine
|
|
199
|
-
--host <id-or-name> Alias for --machine
|
|
200
|
-
|
|
201
|
-
With --project, providers whose requirements are unmet on every persistent
|
|
202
|
-
machine are omitted, and \`--json\` reports each provider's
|
|
203
|
-
\`machineAvailability\` per machine. Add --machine to print that machine's
|
|
204
|
-
availability: \`available\`, \`setup-required\`, \`unavailable\` with the plugin's
|
|
205
|
-
reason, or \`unknown\` while the background check has not answered. Listing
|
|
206
|
-
never waits on a machine; results can be up to ten minutes old, and thread
|
|
207
|
-
creation checks the selected provider and machine afresh.
|
|
208
|
-
bb environment list List environments that are not destroyed
|
|
209
|
-
--project <id> Only environments in this project
|
|
210
|
-
--provider <id> Only environments this environment provider produced
|
|
211
|
-
--host <id-or-name> Only environments on this machine
|
|
212
|
-
--instance-key <key> Only the environment its provider named with
|
|
213
|
-
this instance key (with --provider, the one
|
|
214
|
-
row that provider's launch produced)
|
|
215
|
-
--status <status> Only environments in this status: provisioning,
|
|
216
|
-
ready, error, destroyed (the only way to see
|
|
217
|
-
destroyed rows)
|
|
218
|
-
--limit <n> / --offset <n> Page through the rows, oldest first
|
|
219
|
-
bb environment delete <id> Request provider cleanup; refused while threads are
|
|
220
|
-
live or stopping. The command returns with cleanup
|
|
221
|
-
requested; lifecycle becomes destroyed only after
|
|
222
|
-
provider removal completes
|
|
223
|
-
bb environment cleanup <id> Remove an unused provider-managed environment now
|
|
224
|
-
--recover After inspection, acknowledge interrupted hooks and
|
|
225
|
-
retry failed cleanup (Linux same-user process guard)
|
|
226
|
-
bb environment show <id> Show environment details (path, branch, status, lifecycle, retirement deadline and teardown attempts)
|
|
227
|
-
|
|
228
|
-
bb environment status <id> Show workspace status. Each file list holds at most
|
|
229
|
-
200 entries (tracked changes first); fileCount is
|
|
230
|
-
the total number of changed files
|
|
231
|
-
--merge-base-branch <branch> Include merge-base status
|
|
232
|
-
If squash-merge detection hits its limits (1,000 commits, 1 second),
|
|
233
|
-
mergeBase.squashMergeCheckComplete is false and counts may include
|
|
234
|
-
already squash-merged commits.
|
|
235
|
-
|
|
236
|
-
bb environment branches <id> List local and remote branches
|
|
237
|
-
--query <query> Filter branch names
|
|
238
|
-
--limit <count> Limit local and remote results
|
|
239
|
-
|
|
240
|
-
bb environment paths <id> Search workspace paths
|
|
241
|
-
--query <query> Fuzzy path query
|
|
242
|
-
--limit <count> Maximum results
|
|
243
|
-
--files Include only files unless combined with --directories
|
|
244
|
-
--directories Include only directories unless combined with --files
|
|
245
|
-
|
|
246
|
-
bb environment diff <id> Show file summary and full git diff
|
|
247
|
-
bb environment diff-files <id> List changed-file metadata
|
|
248
|
-
--target <target> uncommitted, branch_committed, all, or commit (required)
|
|
249
|
-
--merge-base-branch <branch> Required for branch_committed and all
|
|
250
|
-
--sha <sha> Required for commit
|
|
251
|
-
--ignore-whitespace Count and diff with git -w; whitespace-only
|
|
252
|
-
files stay listed with +0 -0
|
|
253
|
-
|
|
254
|
-
bb environment diff-file <id> Read one side of a changed file
|
|
255
|
-
--target <target> Diff target (required)
|
|
256
|
-
--path <path> Repository-relative path (required)
|
|
257
|
-
--side <old|new> File side (required)
|
|
258
|
-
--merge-base-ref <sha> Required for branch_committed and all
|
|
259
|
-
--sha <sha> Required for commit
|
|
260
|
-
|
|
261
|
-
bb environment diff-patch <id> Fetch selected file patches
|
|
262
|
-
--target <target> Diff target (required)
|
|
263
|
-
--path <path> Changed path; repeat for multiple files (required)
|
|
264
|
-
--merge-base-branch <branch> Required for branch_committed and all
|
|
265
|
-
--sha <sha> Required for commit
|
|
266
|
-
--ignore-whitespace Patch with git -w; whitespace-only files
|
|
267
|
-
return an empty patch
|
|
268
|
-
|
|
269
|
-
diff-files --json reports each file's revision: old and new git modes and
|
|
270
|
-
blob ids (<oldMode>:<oldBlob>:<newMode>:<newBlob>). Any content or mode
|
|
271
|
-
edit, including whitespace, changes it; staging does not.
|
|
272
|
-
|
|
273
|
-
bb environment diff-viewed list <id> List files marked Viewed
|
|
274
|
-
--path <path> Limit to these paths; repeat up to 500 times (revision, path)
|
|
275
|
-
bb environment diff-viewed mark <id> Mark a file Viewed
|
|
276
|
-
--path <path> Changed path (required)
|
|
277
|
-
--revision <revision> Defaults to the file's current revision
|
|
278
|
-
bb environment diff-viewed unmark <id> Clear Viewed for --path <path>
|
|
279
|
-
bb environment diff-viewed clear <id> Clear Viewed for every file in the target
|
|
280
|
-
All diff-viewed commands take --target, --merge-base-branch, --sha, --json.
|
|
281
|
-
|
|
282
|
-
Viewed mutation commands acknowledge success (\`{ "ok": true }\` with --json);
|
|
283
|
-
use list to read records. Omitting --path from list returns the whole target.
|
|
284
|
-
|
|
285
|
-
Viewed is stored per environment and diff target. A file shows as Viewed
|
|
286
|
-
only while its current revision equals the stored one, so new edits
|
|
287
|
-
un-view it.
|
|
288
|
-
|
|
289
|
-
bb environment update <id> Update environment metadata
|
|
290
|
-
--merge-base-branch <branch> Set merge-base branch override
|
|
291
|
-
--clear-merge-base-branch Clear merge-base override
|
|
292
|
-
--name <name> Set display name
|
|
293
|
-
--clear-name Clear display name
|
|
294
|
-
|
|
295
|
-
bb environment commit <id> Create a commit in the environment
|
|
296
|
-
|
|
297
|
-
bb environment archive-threads <id> Archive all threads in an environment
|
|
298
|
-
|
|
299
|
-
After the last live thread is archived, the environment provider's policy
|
|
300
|
-
sets a retirement deadline; checkout environments never retire. A worktree
|
|
301
|
-
waits five minutes and then tears down: it runs .bb-env-teardown.sh, stops
|
|
302
|
-
every process whose working directory is inside the worktree (the agent
|
|
303
|
-
process, background jobs it left behind, and also shells, editors, or
|
|
304
|
-
servers you started there yourself), removes the worktree, and records the
|
|
305
|
-
environment as destroyed. The branch is kept. Unarchiving a thread inside
|
|
306
|
-
the grace window cancels the teardown. Move your own shells out of the
|
|
307
|
-
worktree first if you want to keep them. Deleting the last thread, or an
|
|
308
|
-
explicit environment or project deletion, skips the grace (including a
|
|
309
|
-
never-retire policy). Failed teardown retries after 1, 2, 4, and 8 minutes, then stops after
|
|
310
|
-
five failed attempts with a "Needs recovery" message;
|
|
311
|
-
\`bb environment show <id>\` reports the lifecycle phase, deadline, teardown
|
|
312
|
-
attempt, and failure message.
|
|
313
|
-
|
|
314
|
-
\`bb environment cleanup <id> [--json]\` overrides retention and retry backoff
|
|
315
|
-
to remove an unused provider-managed environment early. It is not a routine
|
|
316
|
-
end-of-task step. It rejects live threads and unmanaged environments,
|
|
317
|
-
succeeds if already removed, and completes asynchronously. It cannot bypass
|
|
318
|
-
"Needs recovery"; \`bb environment list\` includes the failure message.
|
|
319
|
-
|
|
320
|
-
\`bb environment cleanup <id> --recover [--json]\` is an explicit acknowledgement
|
|
321
|
-
after inspecting a failed environment. It marks interrupted hooks finished,
|
|
322
|
-
resets the retry budget, and retries removal. It also handles interrupted
|
|
323
|
-
setup without a recorded hook operation. A teardown hook that never started
|
|
324
|
-
still runs. A daemon reboot alone never proves a detached hook has stopped.
|
|
325
|
-
|
|
326
|
-
Recovery currently requires Linux. It refuses while a setup/hook is still
|
|
327
|
-
active, while any process owned by the daemon UID has its cwd or a mapped
|
|
328
|
-
file path under the workspace, or while any such process cannot be inspected.
|
|
329
|
-
The guard compares paths, including deleted paths, rather than shared inode
|
|
330
|
-
identity. It does not kill processes. Processes owned by other users require
|
|
331
|
-
separate inspection before recovery. Stop or move your own workspace users
|
|
332
|
-
first. Unsupported platforms and unavailable daemons refuse recovery.
|
|
333
|
-
Existing cleanup callers can use the additive \`recover\` option on
|
|
334
|
-
\`sdk.environments.experimental_cleanup({ environmentId, recover: true })\`.
|
|
335
|
-
Inspect \`bb environment show <id>\` after recovery to confirm removal.
|
|
336
|
-
|
|
337
|
-
Pull requests moved to the bundled GitHub PR Status plugin:
|
|
338
|
-
\`bb pull-request show|ready|draft|merge <environment-id>\`. See its
|
|
339
|
-
github-pr-status skill.
|
|
340
|
-
|
|
341
|
-
Every inspection command accepts an arbitrary environment ID and supports
|
|
342
|
-
\`--json\`. Non-git status/diff responses are reported explicitly. \`diff-file\`
|
|
343
|
-
prints UTF-8 content directly and labels base64 binary content; diff and patch
|
|
344
|
-
truncation markers are preserved.`,variables:{}},{id:"bbGuideJson",body:`JSON output
|
|
345
|
-
|
|
346
|
-
Every core command accepts --json except the plugin authoring tools (\`bb plugin
|
|
347
|
-
new\`, \`types\`, \`migrate\`, \`build\`, \`dev\`, \`run\`, \`logs\`, \`update\`). Success
|
|
348
|
-
prints one JSON value on stdout and exits 0. Nothing else is written to stdout.
|
|
349
|
-
|
|
350
|
-
Errors
|
|
351
|
-
|
|
352
|
-
A failed command exits non-zero. With --json it prints this envelope on stdout
|
|
353
|
-
and still prints the readable message on stderr:
|
|
354
|
-
|
|
355
|
-
{"ok": false, "error": {"code": "unknown_option", "message": "...", "hint": "..."}}
|
|
356
|
-
|
|
357
|
-
\`hint\` is present only when bb knows the fix: the flag to add, the nearest
|
|
358
|
-
command or option, or the usage line. Codes for mistakes in the invocation:
|
|
359
|
-
unknown_command, unknown_option, missing_required, unexpected_argument,
|
|
360
|
-
invalid_value, missing_command. A failed server request uses the server's error
|
|
361
|
-
code, such as thread_not_found or terminal_output_unavailable; otherwise the
|
|
362
|
-
code is http_<status> or error.
|
|
363
|
-
|
|
364
|
-
Parse stdout only. \`2>&1\` mixes the readable message into the JSON, and
|
|
365
|
-
\`2>/dev/null\` hides it. Check the exit code, or test \`.ok == false\`, before
|
|
366
|
-
reading fields.
|
|
367
|
-
|
|
368
|
-
Shapes
|
|
369
|
-
|
|
370
|
-
List commands do not share one wrapper. Most print a bare array; a few wrap it.
|
|
371
|
-
Fields beyond those shown exist; these are the ones scripts use. The \`--help\` of
|
|
372
|
-
the most-parsed commands ends with the same shape.
|
|
373
|
-
|
|
374
|
-
bb status --json
|
|
375
|
-
{project: {id, name} | null, thread: {id, status, title, parentThreadId, environment: {hostId, display} | null} | null, childThreads: [{id, status, title}] | null, pendingTodos, pluginsNeedingAttention: [{id, status}], dataDir}
|
|
376
|
-
|
|
377
|
-
bb thread list --json
|
|
378
|
-
[{id, projectId, environmentId, providerId, title, status, parentThreadId, sectionId, visibility, archivedAt, pinnedAt, createdAt, updatedAt, activity}] (bare array; title can be null)
|
|
379
|
-
|
|
380
|
-
bb thread show <id> --json
|
|
381
|
-
{thread: {id, status, title, projectId, environmentId, parentThreadId, ...}, environment: {id, hostId, path, branchName, ...} | null, pendingTodos} (thread fields are under .thread)
|
|
382
|
-
|
|
383
|
-
bb thread log <id> --json
|
|
384
|
-
[{id, seq, type, createdAt, threadId, scope, data}] (bare array of raw events, oldest first; page with --after-seq <seq>); with --message: {message, before, after} of conversation rows
|
|
385
|
-
|
|
386
|
-
bb thread output <id> --json
|
|
387
|
-
{output}
|
|
388
|
-
|
|
389
|
-
bb thread spawn ... --json
|
|
390
|
-
the created thread: {id, status, title, projectId, environmentId, ...}
|
|
391
|
-
|
|
392
|
-
bb thread tell <id> ... --json
|
|
393
|
-
{threadId, ...delivery outcome}
|
|
394
|
-
|
|
395
|
-
bb thread wait <id> --json
|
|
396
|
-
{threadId, matched: true, target}
|
|
397
|
-
|
|
398
|
-
bb thread count --json
|
|
399
|
-
{total}
|
|
400
|
-
|
|
401
|
-
bb thread search <query> --json
|
|
402
|
-
{active: {total, results}, archived: {total, results}}
|
|
403
|
-
|
|
404
|
-
bb prompt-history list --json
|
|
405
|
-
{entries: [{id, createdAt, input, projectId, threadId, scope}], nextCursor: string | null}
|
|
406
|
-
|
|
407
|
-
bb thread section list --json
|
|
408
|
-
[{id, name, createdAt, updatedAt}]
|
|
409
|
-
|
|
410
|
-
bb thread queue list <id> --json, bb thread interactions list <id> --json, bb thread history <id> --json
|
|
411
|
-
bare arrays
|
|
412
|
-
|
|
413
|
-
bb project list --json
|
|
414
|
-
[{id, kind, name, gitRemoteUrl, sources: [{id, hostId, path, isDefault}]}] (bare array)
|
|
415
|
-
|
|
416
|
-
bb project show <id> --json
|
|
417
|
-
{id, kind, name, gitRemoteUrl, sources}
|
|
418
|
-
|
|
419
|
-
bb machine list --json
|
|
420
|
-
[{id, name, type, status, lifecycle, maxPermissionMode, lastSeenAt}] (bare array)
|
|
421
|
-
|
|
422
|
-
bb provider list --json
|
|
423
|
-
[{id, displayName, available, capabilities, reasoningLevels, serviceTiers}] (bare array)
|
|
424
|
-
|
|
425
|
-
bb provider models [providerId] --json
|
|
426
|
-
[{id, model, displayName, supportedReasoningEfforts, defaultReasoningEffort, supportedServiceTiers?, isDefault}] (bare array)
|
|
427
|
-
|
|
428
|
-
bb environment list --json
|
|
429
|
-
[{id, name, projectId, hostId, path, branchName, status, lifecycle}] (bare array)
|
|
430
|
-
|
|
431
|
-
bb environment show <id> --json
|
|
432
|
-
{id, name, projectId, hostId, path, branchName, baseBranch, status, lifecycle}
|
|
433
|
-
|
|
434
|
-
bb terminal list --thread <id> --json
|
|
435
|
-
{sessions: [{id, title, status, exitCode, closeReason, cols, rows}]} (wrapped in .sessions)
|
|
436
|
-
|
|
437
|
-
bb terminal output <terminalId> --json
|
|
438
|
-
{chunks: [{seq, dataBase64}], nextSeq, truncated, status, exitCode, closeReason} (chunk data is base64; status is "exited" once the command has finished)
|
|
439
|
-
|
|
440
|
-
bb terminal wait <terminalId> ... --json
|
|
441
|
-
{terminalId, matched, nextSeq, exitCode}
|
|
442
|
-
|
|
443
|
-
bb plugin list --json
|
|
444
|
-
{plugins: [{id, version, enabled, status, source, rootDir}]} (wrapped in .plugins)
|
|
445
|
-
|
|
446
|
-
bb skill list --json
|
|
447
|
-
{skills: [{id, name, description, scope, provider, filePath}]} (wrapped in .skills)
|
|
448
|
-
|
|
449
|
-
bb marketplace list --json
|
|
450
|
-
bare array
|
|
451
|
-
|
|
452
|
-
bb settings show --json
|
|
453
|
-
one object keyed by settings area (generalSettings, serverAccess, keybindings, experiments, appearance, ...)
|
|
454
|
-
|
|
455
|
-
bb guide commands [group] --json
|
|
456
|
-
{chapter, commands: [{path, aliases, arguments, options, description}]}
|
|
457
|
-
|
|
458
|
-
Commands contributed by plugins document their own JSON in \`bb <command> --help\`
|
|
459
|
-
and the plugin's skill.`,variables:{}},{id:"bbGuideMachines",body:`Machine commands
|
|
460
|
-
|
|
461
|
-
A host is an identity and daemon connection. A machine is a host with a
|
|
462
|
-
provider-owned lifecycle. The local host has no machine provider. Every other
|
|
463
|
-
host is a machine, including existing machines enrolled with the built-in
|
|
464
|
-
\`manual\` provider (Manual machine setup). Add machines under Settings \u2192 Machines
|
|
465
|
-
or from the composer machine picker.
|
|
466
|
-
|
|
467
|
-
One machine runs the bb server. It stores threads, the database, and settings,
|
|
468
|
-
and every other machine and app connects to it. Settings \u2192 Machines badges it
|
|
469
|
-
\`server\` once there are several persistent machines, and \`bb machine list\` shows
|
|
470
|
-
\`server\` in its Role column. Keep the server machine on: while it is asleep or
|
|
471
|
-
off, nothing can reach bb and running threads may stop. The server machine
|
|
472
|
-
cannot be removed.
|
|
473
|
-
|
|
474
|
-
The server listens on loopback by default. Remote execution machines need
|
|
475
|
-
a server access provider: paired bb Connect, or a configured direct URL reachable
|
|
476
|
-
from the target, such as a private Tailscale Serve URL. A configured URL alone
|
|
477
|
-
does not prove reachability.
|
|
478
|
-
|
|
479
|
-
bb machine list List persistent machines with role, ID, type,
|
|
480
|
-
connection status, and relative last-seen time
|
|
481
|
-
--all Include disposable provider sandboxes
|
|
482
|
-
--json Print the raw host list
|
|
483
|
-
bb machine providers List installed machine providers
|
|
484
|
-
--json Include inputs schemas and policy
|
|
485
|
-
bb machine create --provider <id> Create a standalone machine
|
|
486
|
-
--key <idempotency-key> Reuse this creation on retries
|
|
487
|
-
--inputs <JSON> Non-secret provider inputs
|
|
488
|
-
--no-wait Return the creating host ID immediately
|
|
489
|
-
--json Print the created machine as JSON
|
|
490
|
-
bb machine enroll --bootstrap-file <path>
|
|
491
|
-
--bootstrap-env <NAME> Alternative private bundle source
|
|
492
|
-
bb machine show <id-or-name> Show machine details
|
|
493
|
-
bb machine rename <id-or-name> <name> Rename a machine
|
|
494
|
-
bb machine retry-update <id-or-name> Retry a pending daemon update now
|
|
495
|
-
bb machine reconcile <id-or-name> Reconcile compute with core\u2019s recorded state
|
|
496
|
-
bb machine suspend <id-or-name> Suspend a provider-managed machine
|
|
497
|
-
bb machine resume <id-or-name> Resume a machine (already active is a no-op)
|
|
498
|
-
bb machine retry-cleanup <id-or-name> Retry failed teardown now
|
|
499
|
-
bb machine remove <id-or-name> [--yes] Revoke and remove a machine
|
|
500
|
-
--force Finish removing a disconnected machine whose
|
|
501
|
-
environment cleanup failed; the provider's
|
|
502
|
-
removal still runs
|
|
503
|
-
bb machine provider-cli status <machine>
|
|
504
|
-
bb machine provider-cli install <machine> <provider-id>
|
|
505
|
-
--action <install|update>
|
|
506
|
-
|
|
507
|
-
\`bb machine show\` includes \`threadStorageRootPath\` from the latest daemon
|
|
508
|
-
session without waking the machine (null before the first session).
|
|
509
|
-
\`bb machine list --json\` includes lifecycle phase, progress, and any suspension
|
|
510
|
-
or resume error.
|
|
511
|
-
|
|
512
|
-
Each machine has a permission limit: the highest permission mode any thread on
|
|
513
|
-
that machine can run with. The default is Full Access. A thread that asks for
|
|
514
|
-
more resolves down to the limit, and a provider that supports no mode under the
|
|
515
|
-
limit cannot run there. Set it in Settings \u2192 Machines \u2192 the machine \u2192 Permission
|
|
516
|
-
limit. There is no CLI or SDK command to set it, and a paired machine cannot set
|
|
517
|
-
it for any machine, so a sandbox machine can stay at Full Access while your
|
|
518
|
-
laptop stays lower. \`bb machine list --json\` and \`bb machine show\` report the
|
|
519
|
-
current limit.
|
|
520
|
-
|
|
521
|
-
Standalone create does not create a thread or workspace. Omit inputs to use the
|
|
522
|
-
provider defaults; supply JSON when its schema requires additional values. Omit
|
|
523
|
-
\`--key\` to let the server generate one, or supply a stable key for retries.
|
|
524
|
-
Creation is durable: \`--no-wait\` returns the creating host ID immediately;
|
|
525
|
-
otherwise the CLI polls that host until active. SIGINT stops following and
|
|
526
|
-
exits 130 while creation continues. \`bb machine list\` includes machines still
|
|
527
|
-
being created. Use \`bb machine show <host-id>\` to inspect progress and
|
|
528
|
-
\`bb machine remove <host-id>\` to cancel and clean up. The SDK provides
|
|
529
|
-
\`hosts.experimental_create\`; pass \`wait: false\` to receive the creating host and
|
|
530
|
-
poll it with \`hosts.get\`. Aborting a caller signal never cancels the server
|
|
531
|
-
operation. A connected daemon does not yet imply an agent-ready checkout and
|
|
532
|
-
authenticated provider: thread startup does not install or update agent CLIs or
|
|
533
|
-
probe authentication, so use \`bb machine provider-cli\` for that.
|
|
534
|
-
|
|
535
|
-
Suspend and resume are available only when the machine provider implements
|
|
536
|
-
both operations. Suspending interrupts active turns and closes terminals before
|
|
537
|
-
saving; interrupted turns are never reported successful, so submit a new turn
|
|
538
|
-
after restore. \`bb machine suspend\` polls until the machine is paused, and
|
|
539
|
-
\`bb machine resume\` waits for the provider restore; resume does not rerun
|
|
540
|
-
environment setup. \`bb machine reconcile\` / \`hosts.experimental_reconcile\` is an
|
|
541
|
-
explicit request, not a timer: for a machine core records as suspended, it runs
|
|
542
|
-
the provider's save-and-stop operation, and the CLI polls until completion.
|
|
543
|
-
Active machines and lifecycle operations already in progress are left alone.
|
|
544
|
-
Retry cleanup is accepted only for a retiring machine whose provider teardown
|
|
545
|
-
failed. \`bb machine remove --force\` / \`hosts.delete({ hostId, force: true })\`
|
|
546
|
-
finishes removing a persistent machine that is disconnected and whose
|
|
547
|
-
environment cleanup failed, for example because the computer no longer exists:
|
|
548
|
-
it marks the machine's environments destroyed without running their teardown on
|
|
549
|
-
the machine (files stay on its disk), then runs the provider's removal and
|
|
550
|
-
revokes the machine. It is refused (409) while the machine is connected,
|
|
551
|
-
before teardown has failed, or when no environment cleanup is blocking removal;
|
|
552
|
-
use retry cleanup then.
|
|
553
|
-
|
|
554
|
-
Machines installed from Settings run as launchd or systemd services with
|
|
555
|
-
\`--auto-update\`: when the server is upgraded, each daemon updates its private
|
|
556
|
-
bb install to match and restarts. A daemon never downgrades. Use Settings \u2192
|
|
557
|
-
Machines or \`bb machine retry-update\` to retry a failed update now. To opt out,
|
|
558
|
-
remove \`--auto-update\` from the launchd plist or systemd user unit and reload
|
|
559
|
-
that service; foreground \`bb-app host-daemon\` runs leave it off unless you pass
|
|
560
|
-
\`--auto-update\`.
|
|
561
|
-
|
|
562
|
-
Application logs rotate in \`logs/server.N.log\` and \`logs/host-daemon.N.log\`
|
|
563
|
-
under the selected data directory. Startup errors, crashes, and other output
|
|
564
|
-
that bypasses the logger are appended to \`logs/server-stdio.log\` and
|
|
565
|
-
\`logs/host-daemon-stdio.log\`; a file over 10 MB is renamed to \`-stdio.1.log\`
|
|
566
|
-
when its service starts. Follow them with \`tail -F\`.
|
|
567
|
-
|
|
568
|
-
Updates commands
|
|
569
|
-
|
|
570
|
-
One consolidated view of bb and provider CLI updates across machines \u2014 the
|
|
571
|
-
CLI counterpart of Settings \u2192 Updates.
|
|
572
|
-
|
|
573
|
-
bb updates [status] Show bb-app and provider CLI update status for
|
|
574
|
-
every persistent machine
|
|
575
|
-
--machine <id-or-name> Limit to one machine (including a sandbox)
|
|
576
|
-
--json Print the aggregate as JSON
|
|
577
|
-
bb updates apply Run every available provider CLI install/update,
|
|
578
|
-
one at a time
|
|
579
|
-
--machine <id-or-name> Limit to one machine
|
|
580
|
-
--json Print per-target results as JSON
|
|
581
|
-
bb updates app [status] Show whether bb can update itself, the available
|
|
582
|
-
version, and the last result
|
|
583
|
-
--json Print the status as JSON
|
|
584
|
-
bb updates app apply Download the update and restart bb into it
|
|
585
|
-
--yes Interrupt running threads without asking
|
|
586
|
-
--no-wait Return once the update starts
|
|
587
|
-
--json Print the final status as JSON
|
|
588
|
-
bb updates app dismiss Mark the last update result as seen
|
|
589
|
-
|
|
590
|
-
\`bb updates app apply\` also updates a server hosted by the desktop app, restarting
|
|
591
|
-
that hosting app through its native updater. It never updates the desktop you
|
|
592
|
-
are viewing from unless that desktop hosts this server.
|
|
593
|
-
|
|
594
|
-
\`bb updates apply\` covers provider CLIs only. \`bb updates app apply\` updates
|
|
595
|
-
bb itself when it was started from \`npx bb-app\` (or a global \`bb-app\`) without
|
|
596
|
-
\`--no-in-app-updates\`: it installs the new version next to the running one and
|
|
597
|
-
restarts into it. It does not roll back if the new version fails to start.
|
|
598
|
-
Desktop users update through the desktop app's relaunch, and \`bb-server\` cannot
|
|
599
|
-
update itself. Connected daemons follow the server version automatically.
|
|
600
|
-
|
|
601
|
-
Targeting machines
|
|
602
|
-
|
|
603
|
-
For source installs, \`bb updates\` shows the checkout commit and explains manual
|
|
604
|
-
Git updates when no update shim is running. It does not compare that checkout
|
|
605
|
-
with npm releases. Failed or unavailable release checks show \u201CLatest unknown\u201D;
|
|
606
|
-
\u201CUp to date\u201D requires a successful check.
|
|
607
|
-
|
|
608
|
-
Machine selectors accept either an exact machine ID or an unambiguous machine
|
|
609
|
-
name. \`--host\` is an alias for \`--machine\`.
|
|
610
|
-
|
|
611
|
-
bb thread spawn --project <id> --machine <id-or-name> --prompt "..."
|
|
612
|
-
bb thread spawn --project <id> --new-machine <provider-id> --prompt "..."
|
|
613
|
-
--machine-inputs <json>
|
|
614
|
-
bb project create --name "..." --root <path> --machine <id-or-name>
|
|
615
|
-
bb project source add <projectId> --machine <id-or-name> --path <path>
|
|
616
|
-
|
|
617
|
-
For thread spawning, machine targeting works with an unmanaged workspace path,
|
|
618
|
-
a new managed worktree, or the personal workspace. Do not combine it with an
|
|
619
|
-
existing environment ID: the reused environment already selects its machine.
|
|
620
|
-
\`--new-machine\` creates through a machine provider and always needs an explicit
|
|
621
|
-
\`--environment-provider <id>\`; machine providers do not choose an environment.
|
|
622
|
-
Use \`--environment-inputs <json>\` for workspace configuration, separately from
|
|
623
|
-
\`--machine-inputs <json>\`. Machine inputs are persisted and readable by
|
|
624
|
-
plugins; never put secrets there. Store credentials in plugin settings and pass
|
|
625
|
-
only non-secret configuration or references.
|
|
626
|
-
|
|
627
|
-
An environment provider that composes its own machine, such as
|
|
628
|
-
\`modal-sandbox\`, chooses that machine:
|
|
629
|
-
\`bb thread spawn --project <id> --environment-provider modal-sandbox --prompt "..."\`
|
|
630
|
-
creates the machine, prepares the project checkout, and runs environment setup.
|
|
631
|
-
Machine selectors are refused, and \`--machine-inputs <json>\` configures the
|
|
632
|
-
machine (for example \`{"preset":"Large","image":"Node 22"}\`). Progress and
|
|
633
|
-
failures appear in the thread's provisioning details; if cloning fails, the
|
|
634
|
-
machine remains available for retry or explicit removal.
|
|
635
|
-
|
|
636
|
-
When \`--new-machine\` or a composed provider needs a project checkout, core
|
|
637
|
-
clones the project's Git remote and registers a source on the new machine
|
|
638
|
-
before creating the environment. Existing sources are reused, and a completed
|
|
639
|
-
checkout whose remote matches is registered instead of cloned again; a
|
|
640
|
-
conflicting target is refused. bb owns a checkout it cloned (here or with
|
|
641
|
-
\`project source add --clone\`), so environments in it run \`.bb-env-setup.sh\`
|
|
642
|
-
and \`.bb-env-teardown.sh\`. The project needs a Git remote and the machine needs
|
|
643
|
-
Git access to it. Choosing Personal workspace does not clone a project.
|
|
644
|
-
Standalone \`bb machine create\` does not set up a project source and remains
|
|
645
|
-
available until explicitly removed. Machines created for threads retire after
|
|
646
|
-
their last live thread is archived when the provider declares them ephemeral.
|
|
647
|
-
|
|
648
|
-
For project creation and sources, \`--root\`/\`--path\` refers to a path on the
|
|
649
|
-
selected connected machine. Omit the selector to keep the existing local CLI
|
|
650
|
-
machine fallback (normally the server machine). Pass \`--clone\` to source add
|
|
651
|
-
instead of \`--path\` to clone the project's Git remote there; \`--remote-url\` and
|
|
652
|
-
\`--target-path\` optionally override the clone inputs.
|
|
653
|
-
|
|
654
|
-
## Server access
|
|
655
|
-
|
|
656
|
-
Set Machines \u2192 Server URL reachable by machines, or run \`bb settings general
|
|
657
|
-
machineServerUrl https://bb.example.com\`. An unset value uses BB_EXTERNAL_URL.
|
|
658
|
-
Set Default machine access with
|
|
659
|
-
\`bb settings general defaultMachineAccess direct\` or \`connect\`; \`null\` uses
|
|
660
|
-
the first registered access provider, or direct when none is registered. An
|
|
661
|
-
unpaired provider reports setup required. \`bb settings show --json\` includes
|
|
662
|
-
fresh provider availability and the effective selection; failed or timed-out
|
|
663
|
-
checks report unavailable. Machines use this access for ongoing runtime
|
|
664
|
-
requests, including account-pool endpoints. A machine on bb connect access holds
|
|
665
|
-
a getbb.app machine credential that \`bb machine remove\` revokes; if that
|
|
666
|
-
revocation fails, revoke the machine in the getbb.app dashboard.
|
|
667
|
-
|
|
668
|
-
Remote access through getbb.app comes from the bundled bb account and Connect
|
|
669
|
-
plugins: \`bb account login|status|logout\` signs this server in (bb-account
|
|
670
|
-
skill), and \`bb connect status|on|off|expose|unexpose|unexpose-all|shares\`
|
|
671
|
-
serves it at \`<handle>.getbb.app\` and shares HTTP ports from any enrolled host
|
|
672
|
-
(share-server-links skill). \`bb connect servers\` lists every bb on the account.
|
|
673
|
-
\`bb connect machine-code\` mints a one-time, 10-minute code that pairs the bb
|
|
674
|
-
mobile app (also shown under Settings \u2192 Mobile \u2192 Add mobile device); \`--json\`
|
|
675
|
-
prints \`{code, serverUrl, apex, expiresAt}\`. Without an installed bb, pair a
|
|
676
|
-
dashboard code with \`npx -p bb-app@latest bb connect --code <code>\`.
|
|
677
|
-
|
|
678
|
-
## Move the server
|
|
679
|
-
|
|
680
|
-
Moving the server is experimental and off by default. Turn on the \`serverMove\`
|
|
681
|
-
experiment in Settings \u2192 Experiments or with
|
|
682
|
-
\`bb settings experiment serverMove true\`; until then Settings \u2192 Machines hides
|
|
683
|
-
Move server here, and \`bb server move\`, \`bb server export\`, and deleting an old
|
|
684
|
-
server copy from the server are refused with \`server_move_experiment_disabled\`.
|
|
685
|
-
|
|
686
|
-
Agents must not move a server, abandon a move, or unlock an old copy without
|
|
687
|
-
the user's explicit confirmation in the conversation. Run \`--check\`, show the
|
|
688
|
-
user the checklist, and wait for their confirmation; don't pass \`--yes\` to skip
|
|
689
|
-
the confirmation on their behalf.
|
|
690
|
-
|
|
691
|
-
A move copies the server's data (database, settings, plugin data, attachments)
|
|
692
|
-
to another persistent machine, points every machine and app at it, and keeps the
|
|
693
|
-
old computer running as a regular machine. Worktrees, thread storage, and
|
|
694
|
-
checkouts stay on the machines that own them.
|
|
695
|
-
|
|
696
|
-
bb server move --to <id-or-name> Stop all work and move the server
|
|
697
|
-
--check Print the checklist and stop
|
|
698
|
-
--address <url> New server address (direct setups)
|
|
699
|
-
--archive-existing-data Move bb server data on the target aside
|
|
700
|
-
--yes Skip the confirmation
|
|
701
|
-
--json Print the final move status
|
|
702
|
-
bb server move status Show the steps, or the last move
|
|
703
|
-
bb server move cancel Cancel before the switch starts
|
|
704
|
-
--yes Abandon a move that needs recovery without asking
|
|
705
|
-
bb server export --out <file> Export a running server
|
|
706
|
-
bb server import <file> Install an export on this computer
|
|
707
|
-
--data-dir <dir> Target data directory
|
|
708
|
-
bb server unlock Let this computer's old copy start again
|
|
709
|
-
--force Skip the new-server health check
|
|
710
|
-
bb server allow-connect Turn bb connect and bb account on for an imported copy
|
|
711
|
-
bb server delete-old-copy Delete the old copy a move left here
|
|
712
|
-
bb server install-machine-service Keep this computer connected after a move
|
|
713
|
-
|
|
714
|
-
\`--check\` exits nonzero while a blocker remains. With bb connect, machines and
|
|
715
|
-
apps keep the same URL. A direct-address server needs \`--address\`: the URL every
|
|
716
|
-
machine and app will use to reach the new server. Existing bb server data on the
|
|
717
|
-
target is archived to \`<dir>.before-move-<date>\` only with
|
|
718
|
-
\`--archive-existing-data\`; it is never merged. SIGINT stops following while the
|
|
719
|
-
move continues. Failure or cancellation before the switch leaves the server
|
|
720
|
-
where it was. The SDK equivalents are \`sdk.experimental_server.checkMove\`,
|
|
721
|
-
\`startMove\`, \`moveStatus\`, \`cancelMove\`, and \`export\`.
|
|
722
|
-
|
|
723
|
-
\`bb server move\` exits 0 once moved and 1 when the move fails or is cancelled.
|
|
724
|
-
When the target never confirms that it took over, the move waits in
|
|
725
|
-
\`recovery_required\`: the old server stays up and read-only, and bb finishes the
|
|
726
|
-
move on its own once the target answers. \`bb server move\` and
|
|
727
|
-
\`bb server move status\` exit 2 in that state and name the exits:
|
|
728
|
-
\`bb server move cancel\` abandons the move and keeps the server here (it asks
|
|
729
|
-
first, since abandoning while the target took over leaves two servers; \`--yes\`
|
|
730
|
-
skips the question), and \`bb server unlock\` recovers an old copy that stopped.
|
|
731
|
-
|
|
732
|
-
\`bb server export\` writes a gzip archive to a 0600 file. The archive is not
|
|
733
|
-
encrypted and holds the server's credentials and plugin secrets, so keep it
|
|
734
|
-
private. \`bb server import\` works offline: it refuses a data directory that has
|
|
735
|
-
\`bb.db\` or a running bb and an export made by a newer bb or with the
|
|
736
|
-
\`serverMove\` experiment off. Rerunning an interrupted import rolls it back
|
|
737
|
-
first (\`--json\` reports \`rolledBackInterruptedImport: true\`). An imported
|
|
738
|
-
server starts with bb connect and bb account off so it can't take the original
|
|
739
|
-
server's tunnel or account; stop the original server, then run
|
|
740
|
-
\`bb server allow-connect\` to turn them on at the next start.
|
|
741
|
-
|
|
742
|
-
After a move, bb on the old computer refuses to start the old server and runs as
|
|
743
|
-
a regular machine. \`bb server delete-old-copy\` deletes the server files left
|
|
744
|
-
behind and keeps that lock. The desktop app installs the persistent machine
|
|
745
|
-
service itself; after a move from \`bb-app\`, or to retry, run
|
|
746
|
-
\`bb server install-machine-service\` (macOS and Linux; needs Node.js 22.19 or
|
|
747
|
-
newer on the PATH). \`bb server unlock\` is a last resort: everything since the
|
|
748
|
-
move is lost on that copy, it refuses while the new server still answers unless
|
|
749
|
-
\`--force\` is passed, and it refuses while the machine service is installed.
|
|
750
|
-
\`unlock\`, \`delete-old-copy\`, \`allow-connect\`, and \`install-machine-service\`
|
|
751
|
-
act on \`BB_DATA_DIR\` or \`~/.bb\` unless \`--data-dir <dir>\` is passed.
|
|
752
|
-
|
|
753
|
-
## Local daemon lifecycle
|
|
754
|
-
|
|
755
|
-
Reconnect a disconnected machine whose server access or host key was revoked
|
|
756
|
-
or became stale, without changing its BB host ID:
|
|
757
|
-
|
|
758
|
-
bb machine reconnect <id-or-name> Print a short-lived reconnect command and wait for reconnection
|
|
759
|
-
(refused for a connected machine)
|
|
760
|
-
--json Print the command and expiry without waiting
|
|
761
|
-
|
|
762
|
-
Run the printed command on the affected machine; if it fails, run it again. The
|
|
763
|
-
machine re-enrolls with a new host key and server access and restarts its
|
|
764
|
-
daemon service. Environments, workspaces, and thread associations are kept. The
|
|
765
|
-
command reuses the data directory the daemon last reported (an explicit
|
|
766
|
-
\`BB_DATA_DIR\` takes precedence) and refuses a directory that does not hold this
|
|
767
|
-
machine. The server's own machine cannot be reconnected this way.
|
|
768
|
-
|
|
769
|
-
\`install-machine.sh --start|--stop|--uninstall --host-id <id>\` starts, stops, or
|
|
770
|
-
removes an owned local installation; optional \`--server-url <url>\` and
|
|
771
|
-
\`--data-dir <path>\` (or \`BB_DATA_DIR\`) assert the expected installation, and a
|
|
772
|
-
mismatch refuses the operation. Stop and uninstall succeed when no matching
|
|
773
|
-
installation exists; start requires one. They refuse the default BB data
|
|
774
|
-
directory. \`install-machine.sh --adopt --data-dir <path>\` installs the service
|
|
775
|
-
for a directory that is already enrolled. These are local primitives:
|
|
776
|
-
\`bb machine remove\` asks the server to remove the provider resource, and
|
|
777
|
-
\`bb machine suspend\` invokes provider suspension.
|
|
778
|
-
|
|
779
|
-
## Enroll a preinstalled machine
|
|
780
|
-
|
|
781
|
-
\`bb machine enroll --bootstrap-file <path>\` or \`bb machine enroll --bootstrap-env <NAME>\` consumes a private enrollment bundle prepared by core. Supply exactly one source. The environment variable is removed from the CLI process after reading it; files remain under the caller's ownership. Neither command prints the bundle or credentials.
|
|
782
|
-
|
|
783
|
-
The CLI refuses another host or server identity in the selected machine directory. Repeating enrollment with the same persisted identity succeeds, including after the original bundle expired. Machine data defaults to \`~/.bb-machines/<server-host>\`; \`BB_DATA_DIR\` can select another isolated machine directory, but enrollment refuses the default \`~/.bb\` directory unless its \`host-id\` already names this machine.
|
|
784
|
-
|
|
785
|
-
The installer accepts \`--bootstrap-env <NAME>\` and installs a private CLI at \`~/.local/bin/bb\` without replacing an existing path; non-login transports can use \`command -v bb\` with \`~/.local/bin/bb\` as a fallback. On a systemd host whose user bus is unreachable, installation fails before enrolling; containers and machines without systemd as init run a detached daemon. \`BB_INSTALL_SKIP_SERVICE=1\` leaves a detached daemon that does not start after reboot.
|
|
786
|
-
|
|
787
|
-
## Existing machines
|
|
788
|
-
|
|
789
|
-
\`bb machine create --provider manual\` waits for a private enrollment command,
|
|
790
|
-
prints it once with its expiry, and follows the host until the daemon connects.
|
|
791
|
-
Run that command on the target machine; it installs bb if needed. The CLI
|
|
792
|
-
prints a command for macOS and Linux and a PowerShell command for Windows.
|
|
793
|
-
Treat it as a credential. It cannot be renewed and does not survive a server
|
|
794
|
-
restart: after it expires, remove the machine and create it again (the app
|
|
795
|
-
offers Generate new command). Server access is resolved through the selected
|
|
796
|
-
default access provider. \`--no-wait\` returns the creating host ID.
|
|
797
|
-
|
|
798
|
-
On Windows, the command installs under
|
|
799
|
-
\`%USERPROFILE%\\.bb-machines\\<server-host>\`, starts the daemon at sign-in, and
|
|
800
|
-
needs Node.js 22.19 or newer on PATH. Manage it with
|
|
801
|
-
\`node <machine-dir>\\install-machine-windows.mjs --stop|--start|--uninstall --host-id <id>\`.
|
|
802
|
-
|
|
803
|
-
Use \`bb machine show <host-id>\` to recover progress and
|
|
804
|
-
\`bb machine remove <host-id>\` to cancel and revoke enrollment/access. Stopping
|
|
805
|
-
the CLI or closing the dialog only stops following; creation continues.
|
|
806
|
-
Manual machines never idle-suspend or automatically retire and do not expose
|
|
807
|
-
suspend/resume. Removing one revokes its server access without executing on the
|
|
808
|
-
machine. Run the original installer with \`--uninstall --host-id <host-id>\` on that box, with its
|
|
809
|
-
original \`BB_DATA_DIR\` if explicitly configured, to remove its installation.
|
|
810
|
-
|
|
811
|
-
## Machine environment
|
|
812
|
-
|
|
813
|
-
bb machine env list [--project <id>] [--json]
|
|
814
|
-
bb machine env set NAME [--project <id>] [--note text] [--json]
|
|
815
|
-
bb machine env unset NAME [--project <id>] [--json]
|
|
816
|
-
|
|
817
|
-
\`set\` reads the value from stdin, removing one trailing newline; values are
|
|
818
|
-
never accepted in argv and never returned by list or set. List masks all values,
|
|
819
|
-
includes built-in GitHub health, and for project scope includes inherited
|
|
820
|
-
global rows. Set and unset update one variable atomically. SDK:
|
|
821
|
-
\`system.machineEnvironment()\` and \`system.replaceMachineEnvironment({ variables })\`;
|
|
822
|
-
replacement is atomic, so pass every row to retain, using \`value: null\` for an
|
|
823
|
-
unchanged saved secret. Settings \u2192 Environment variables (and Project settings \u2192
|
|
824
|
-
Advanced settings for one project) edits the same variables; saved secrets can be
|
|
825
|
-
replaced but never revealed.
|
|
826
|
-
|
|
827
|
-
Omit \`--project\` for global variables. Project overrides follow the project
|
|
828
|
-
across machines and worktrees, including the primary host, and override global
|
|
829
|
-
values. Empty strings override; unset restores inheritance. User variables
|
|
830
|
-
override built-in values on every connected host; agent-provider variables win
|
|
831
|
-
over them for agent turns. All values are encrypted at rest.
|
|
832
|
-
|
|
833
|
-
Changes apply to the next agent turn, new terminals and commands (including git
|
|
834
|
-
and gh operations), and repository setup, which receives freshly resolved values
|
|
835
|
-
on each run. Existing processes, terminals, and cached provider runtimes keep
|
|
836
|
-
their launch environment until recreated. Removing an override restores the
|
|
837
|
-
daemon's original value. Runtime output is forwarded as-is, so commands and
|
|
838
|
-
providers can print these values.
|
|
839
|
-
|
|
840
|
-
The server's gh login provides GitHub credentials, Git HTTPS and SSH access,
|
|
841
|
-
and commit identity to non-primary hosts. The primary host uses its local Git
|
|
842
|
-
authentication unless a user supplies an explicit global or project GH_TOKEN.
|
|
843
|
-
The built-in GH_TOKEN row reports logged in, not logged in, or overridden; a
|
|
844
|
-
custom GH_TOKEN overrides it. No credentials are installed in images or global
|
|
845
|
-
Git config. \`bb settings general machineGitCredentialsEnabled false\` (the
|
|
846
|
-
automatic GH_TOKEN switch in Settings \u2192 Environment variables) stops forwarding
|
|
847
|
-
the server's gh credentials; \`true\` enables it again. This does not log the
|
|
848
|
-
server out or suppress an explicit custom GH_TOKEN.`,variables:{}},{id:"bbGuideOverview",body:`bb is an agent orchestration tool for managing multiple agents.
|
|
849
|
-
|
|
850
|
-
Core concepts:
|
|
851
|
-
|
|
852
|
-
- Project \u2014 maps to a repository. All threads belong to a project.
|
|
853
|
-
- Thread \u2014 a single agent conversation. The fundamental unit of work.
|
|
854
|
-
- Environment \u2014 where a thread runs. Kinds: project checkout or isolated worktree. Multiple threads can share an environment.
|
|
855
|
-
- Machine \u2014 an execution host where project sources and thread environments live.
|
|
856
|
-
- Terminal \u2014 a persistent PTY session scoped to a thread, environment, or machine path. Use terminals for long-running commands such as dev servers.
|
|
857
|
-
- Provider \u2014 the agent backend powering a thread (e.g., codex, claude-code). Each provider supports different models.
|
|
858
|
-
|
|
859
|
-
Threads can have a parent-child relationship. The parent coordinates the child and receives lifecycle notifications when it completes, fails, or is interrupted. Threads without a parent are managed directly by the user.
|
|
860
|
-
|
|
861
|
-
Context variables set automatically inside a thread environment:
|
|
862
|
-
|
|
863
|
-
- BB_PROJECT_ID \u2014 current project
|
|
864
|
-
- BB_THREAD_ID \u2014 current thread
|
|
865
|
-
- BB_ENVIRONMENT_ID \u2014 current environment
|
|
866
|
-
- BB_CLI \u2014 absolute path to the daemon-managed \`bb\` executable (prefer this if bare \`bb\` is wrong; official entrypoints also re-exec to it)
|
|
867
|
-
|
|
868
|
-
Outside a thread the CLI targets http://127.0.0.1:38886; set BB_SERVER_URL (and
|
|
869
|
-
BB_HOST_DAEMON_PORT) only for a deliberate non-default target.
|
|
870
|
-
|
|
871
|
-
Run \`bb status\` to see your current context (resolved project and thread IDs).
|
|
872
|
-
It also warns when an enabled plugin is not running (incompatible after a bb
|
|
873
|
-
upgrade, failed to load, or missing); run \`bb plugin list\` for the detail.
|
|
874
|
-
|
|
875
|
-
All commands support --json for machine-readable output. With --json a failure
|
|
876
|
-
prints \`{"ok": false, "error": {code, message, hint}}\` on stdout; \`bb guide json\`
|
|
877
|
-
lists the output shape of each command.
|
|
878
|
-
|
|
879
|
-
Pass long or multi-line text from a file, not inline: \`bb thread tell <id>
|
|
880
|
-
--message-file <path>\` and \`bb thread spawn --prompt-file <path>\` (use \`-\` for
|
|
881
|
-
stdin). Inside double quotes the shell runs \`backticks\` and \`$(...)\` before bb
|
|
882
|
-
sees the message.
|
|
883
|
-
|
|
884
|
-
Transcribe audio files, such as attached voice memos, with \`bb voice transcribe
|
|
885
|
-
<path>\`. It uses the voice service chosen with \`bb settings ai-services\`;
|
|
886
|
-
\`bb guide customization\` lists its size limits.
|
|
887
|
-
|
|
888
|
-
When a command fails, read the whole error: bb prints the nearest command or
|
|
889
|
-
option, the flag to add with the current project, thread, or machine ID filled
|
|
890
|
-
in, and the usage line. \`bb guide commands <group>\` lists every command in a
|
|
891
|
-
group with its options on one page. Failures are logged without argument values
|
|
892
|
-
to <dataDir>/logs/cli-errors.jsonl; \`bb diagnostics cli-errors [--since 7d]
|
|
893
|
-
[--clear]\` tallies or deletes it, and BB_CLI_ERROR_LOG=0 turns logging off.
|
|
894
|
-
|
|
895
|
-
To make a repo work with bb worktrees, run \`bb guide environments\` for the
|
|
896
|
-
repo-level \`.bb-env-setup.sh\` and \`.bb-env-teardown.sh\` hooks. Run \`bb guide
|
|
897
|
-
agent-configuration\` for the data-dir and workspace files that customize agent
|
|
898
|
-
behavior.
|
|
899
|
-
|
|
900
|
-
Run \`bb guide <chapter>\` for command details:
|
|
901
|
-
|
|
902
|
-
threads Spawning, handing off, forking, and editing threads
|
|
903
|
-
thread-inspection Listing, inspecting, waiting on, and opening threads
|
|
904
|
-
thread-messaging Messages, interactions, and queued messages
|
|
905
|
-
thread-lifecycle Stopping, clearing, retrying, archiving, and deleting
|
|
906
|
-
environments Environment lifecycle hooks, operations, commits, and merges
|
|
907
|
-
agent-configuration AGENTS.md and skills files that shape agents
|
|
908
|
-
providers Discovering providers and models
|
|
909
|
-
projects Project CRUD and sources
|
|
910
|
-
machines Listing and targeting execution machines, moving the
|
|
911
|
-
server
|
|
912
|
-
terminals Persistent PTY sessions across all supported scopes
|
|
913
|
-
browser Experimental built-in browser tabs and control leases
|
|
914
|
-
customization Theme, server-backed settings, keyboard shortcuts,
|
|
915
|
-
sidebar preferences, host files, voice
|
|
916
|
-
plugins Installing plugins, plugin marketplaces, bundled
|
|
917
|
-
plugins, and their contributed bb commands
|
|
918
|
-
json The --json contract: output shapes and the error envelope
|
|
919
|
-
commands [group] Every core command on one page; add a group for options`,variables:{}},{id:"bbGuidePlugins",body:`Plugin commands
|
|
920
|
-
|
|
921
|
-
A bb plugin is a TypeScript package that extends bb with server code, an
|
|
922
|
-
optional entry that runs on enrolled hosts, UI, agent skills and tools, and
|
|
923
|
-
\`bb\` CLI subcommands. Plugins are full-trust code.
|
|
924
|
-
|
|
925
|
-
Builtin plugins (\`builtin:<name>\`) ship with bb and install automatically.
|
|
926
|
-
Official store plugins ship with the app and install on request; third-party
|
|
927
|
-
plugins come from marketplaces, Git, npm, or a local path. Plugin state lives
|
|
928
|
-
under \`<bb-data-dir>/plugins/<id>/\` (SQLite database, secrets, logs).
|
|
929
|
-
|
|
930
|
-
bb plugin search <query> Search the store: the bundled official
|
|
931
|
-
plugins plus every registered marketplace.
|
|
932
|
-
Matches id, name, description, category, or
|
|
933
|
-
tag; status shows installed, compatible,
|
|
934
|
-
requires newer bb, or \`id in use by <source>\`
|
|
935
|
-
bb plugin install <entry> Install an official plugin by name (docs,
|
|
936
|
-
memory, tasks, github, ...),
|
|
937
|
-
<entry-id>@<marketplace>, a Git repository
|
|
938
|
-
URL, a local path, builtin:<name>,
|
|
939
|
-
git:<url>[@<ref|semver-range>], or
|
|
940
|
-
npm:<package>[@<version|tag|range>].
|
|
941
|
-
Installs ask for confirmation; --yes skips it.
|
|
942
|
-
--subdirectory <path> or --plugin <name>
|
|
943
|
-
selects one plugin of a multi-plugin
|
|
944
|
-
repository; --tag-prefix <prefix> scopes a
|
|
945
|
-
git: semver range. Installing a local path
|
|
946
|
-
for an id already installed from another
|
|
947
|
-
path moves it and keeps its settings.
|
|
948
|
-
Installs run one at a time as server jobs
|
|
949
|
-
that continue if the CLI or app disconnects;
|
|
950
|
-
a repeat request joins the active job.
|
|
951
|
-
--no-wait starts the job and prints its id
|
|
952
|
-
bb plugin install-jobs List queued, running, and recently finished
|
|
953
|
-
installs (--json for the jobs)
|
|
954
|
-
bb plugin cancel-install <job> Cancel an install: a queued job is dropped;
|
|
955
|
-
a running job stops its download or build
|
|
956
|
-
and installs nothing, unless it already
|
|
957
|
-
started registering, which then finishes
|
|
958
|
-
bb plugin outdated Check installed plugins for compatible
|
|
959
|
-
updates (--json for raw results), including
|
|
960
|
-
newer releases blocked by engine ranges
|
|
961
|
-
bb plugin update <id> | --all Apply compatible updates for one plugin or
|
|
962
|
-
every tracking plugin. Same confirmation as
|
|
963
|
-
install (--yes skips; non-TTY refuses
|
|
964
|
-
without --yes)
|
|
965
|
-
bb plugin list Status, services, schedules, handler timings,
|
|
966
|
-
and contributed CLI commands. \`bb status\`
|
|
967
|
-
also names enabled plugins that are
|
|
968
|
-
incompatible, failed, or missing
|
|
969
|
-
bb plugin source <id> [--json] Requested and resolved source, subdirectory,
|
|
970
|
-
semver range and resolved tag, engine ranges,
|
|
971
|
-
install time, and recent activation history
|
|
972
|
-
bb plugin enable|disable <id> Load or unload an installed plugin. A
|
|
973
|
-
builtin you never toggled follows bb's
|
|
974
|
-
default; an explicit choice persists across
|
|
975
|
-
releases
|
|
976
|
-
bb plugin safe-mode [on|off] Show or change safe mode. \`on\` stops every
|
|
977
|
-
plugin you installed (official store plugins
|
|
978
|
-
included) without changing its enabled
|
|
979
|
-
setting; builtins keep running. \`off\`
|
|
980
|
-
restarts them and exits 1 if any fail.
|
|
981
|
-
Installs and updates of stopped plugins are
|
|
982
|
-
refused until it is off
|
|
983
|
-
bb plugin reload [id] Restart plugins on their current sources.
|
|
984
|
-
Exits 1 when one does not come up (the
|
|
985
|
-
previous instance is kept or degraded)
|
|
986
|
-
bb plugin config <id> [set <key> <value> | unset <key>]
|
|
987
|
-
Show or change a plugin's declared settings.
|
|
988
|
-
Running plugins receive changes live; a
|
|
989
|
-
plugin waiting for configuration retries
|
|
990
|
-
bb plugin logs <id> [-n N] [-f] Print (or follow) a plugin's log
|
|
991
|
-
bb plugin run <id> [args...] Run a plugin command explicitly (also works
|
|
992
|
-
when a core command owns its name)
|
|
993
|
-
bb plugin token <id> [--rotate] Print the token for a plugin's
|
|
994
|
-
token-authenticated HTTP routes; --rotate
|
|
995
|
-
replaces it
|
|
996
|
-
bb plugin remove <id> Uninstall and delete the plugin's settings,
|
|
997
|
-
secrets, and schedules (local path sources
|
|
998
|
-
stay on disk; builtin removals are
|
|
999
|
-
remembered)
|
|
1000
|
-
bb plugin prune [--dry-run] Delete cached git:/npm: plugin versions no
|
|
1001
|
-
installed plugin uses (left by earlier bb
|
|
1002
|
-
releases, rolled-back updates, or
|
|
1003
|
-
interrupted operations) and leftover cache
|
|
1004
|
-
directories, and print what was freed.
|
|
1005
|
-
Updates and removals already delete what
|
|
1006
|
-
they replace. Never touches a running
|
|
1007
|
-
version or a local path source. Also in the
|
|
1008
|
-
command palette
|
|
1009
|
-
|
|
1010
|
-
bb marketplace add <source> Add a marketplace from an https manifest URL,
|
|
1011
|
-
git:<url>[@<ref>], or path:<directory>.
|
|
1012
|
-
Adding a marketplace installs nothing. For a
|
|
1013
|
-
git: source, --subdirectory <path> reads
|
|
1014
|
-
marketplace.json from that directory of the
|
|
1015
|
-
repository instead of its root
|
|
1016
|
-
bb marketplace list Name, source, entry count, and last refresh
|
|
1017
|
-
(--json for raw rows)
|
|
1018
|
-
bb marketplace refresh [name] Re-read one catalog or all of them. Never
|
|
1019
|
-
installs, updates, or runs plugin code; a
|
|
1020
|
-
failed refresh keeps the last valid catalog
|
|
1021
|
-
and exits non-zero
|
|
1022
|
-
bb marketplace remove <name> Forget a marketplace. Plugins installed from
|
|
1023
|
-
it keep running as direct installs and keep
|
|
1024
|
-
updating from their recorded source.
|
|
1025
|
-
bb-official and bb-community cannot be
|
|
1026
|
-
removed
|
|
1027
|
-
|
|
1028
|
-
Installed plugins and their settings also appear under Settings \u2192 Installed
|
|
1029
|
-
plugins.
|
|
1030
|
-
|
|
1031
|
-
Plugin CLI commands
|
|
1032
|
-
|
|
1033
|
-
A plugin can register one top-level \`bb\` subcommand (for example
|
|
1034
|
-
\`bb github \u2026\`); run it like any core command. Core command names win on a
|
|
1035
|
-
collision, and \`bb plugin list\` then shows the \`bb plugin run <id>\` form.
|
|
1036
|
-
Inside agent threads the generated \`plugin-commands\` skill lists every
|
|
1037
|
-
available plugin command. Most plugin commands accept \`--json\` and \`--help\`.
|
|
1038
|
-
|
|
1039
|
-
Bundled plugins
|
|
1040
|
-
|
|
1041
|
-
Each bundled plugin documents its commands and behavior in its own skill.
|
|
1042
|
-
|
|
1043
|
-
- Prompt Library (builtin, disabled by default): enable with
|
|
1044
|
-
\`bb plugin enable bb--prompt-library\`. Open **+ \u2192 Prompts\u2026** or press
|
|
1045
|
-
**Ctrl+R** to search, preview, star, and insert prompts. Its commands and
|
|
1046
|
-
behavior are documented in the \`prompt-library\` skill.
|
|
1047
|
-
- Custom instructions (builtin): up to 4,096 characters saved under
|
|
1048
|
-
Settings \u2192 Custom instructions are added to every agent task on this host.
|
|
1049
|
-
\`bb instructions get\`, \`bb instructions set <text...>\`, and
|
|
1050
|
-
\`bb instructions clear\`.
|
|
1051
|
-
- Account Pooler (builtin, off by default): pools Claude and Codex accounts
|
|
1052
|
-
behind the bb server with quota-aware failover. Run
|
|
1053
|
-
\`bb plugin enable account-pool\`, then \`bb pool account add\`,
|
|
1054
|
-
\`bb pool status\`, and \`bb pool routing\`; see the \`account-pool\` skill.
|
|
1055
|
-
- Keep Awake (builtin): prevents idle sleep on selected macOS and Windows
|
|
1056
|
-
hosts while bb runs; closing the lid still sleeps.
|
|
1057
|
-
\`bb keep-awake status|enable|disable [--json]\`, \`bb keep-awake hosts all\`,
|
|
1058
|
-
or \`bb keep-awake hosts <host-id>...\`.
|
|
1059
|
-
- Concurrency limit (builtin): caps running threads overall and per host.
|
|
1060
|
-
\`bb concurrency-limit status|global|host\`; see the \`concurrency-limit\`
|
|
1061
|
-
skill.
|
|
1062
|
-
- Provider retry (builtin): queues an automatic retry after provider
|
|
1063
|
-
overloads, server or connection errors, and subscription-window limits.
|
|
1064
|
-
\`bb provider-retry status|explain|retry|cancel\`; see the \`provider-retry\`
|
|
1065
|
-
skill.
|
|
1066
|
-
- Thread list (builtin): owns the sidebar's layout preferences, synced to
|
|
1067
|
-
every window. \`bb thread-list prefs list|get|set|reset\`; see the
|
|
1068
|
-
\`thread-list\` skill.
|
|
1069
|
-
- Push notifications (builtin): notifies mobile, web, and desktop clients
|
|
1070
|
-
when a thread needs attention.
|
|
1071
|
-
\`bb push-notifications status|list|add|remove|test|thread\`; see the
|
|
1072
|
-
\`push-notifications\` skill.
|
|
1073
|
-
- Secrets (builtin): \`bb secret request <NAME...> --write-env <path>\` collects
|
|
1074
|
-
credentials through a secure form into a dotenv file without exposing them
|
|
1075
|
-
to the agent; see the \`secrets\` skill.
|
|
1076
|
-
- Inline previews (builtin): shows an HTML page inline in a reply, from a
|
|
1077
|
-
fenced \`inline-vis\` code block or a \`::inline-vis{file="demo.html"}\`
|
|
1078
|
-
workspace or thread-storage file; see the \`inline-vis\` skill.
|
|
1079
|
-
- MCP server (builtin, disabled by default): \`bb plugin enable bb--mcp\` lets
|
|
1080
|
-
ChatGPT, Claude, or another MCP client control this bb; an approved app can
|
|
1081
|
-
run any \`bb\` command. \`bb mcp status|clients|revoke\`; see the \`mcp\` skill.
|
|
1082
|
-
- Storage & retention (builtin, disabled by default): enable with
|
|
1083
|
-
\`bb plugin enable bb--storage-retention\`. Owns thread retention policies
|
|
1084
|
-
and machine storage cleanup through its sidebar panel and \`bb storage\`
|
|
1085
|
-
commands; see the \`storage-retention\` skill.
|
|
1086
|
-
- Automations (builtin): recurring or one-shot agent prompts and stored
|
|
1087
|
-
server scripts. \`bb automation create|list|show|update|pause|resume|run|runs|delete\`;
|
|
1088
|
-
see the \`automations\` skill.
|
|
1089
|
-
- Workflows (builtin, off by default): durable JavaScript orchestration of
|
|
1090
|
-
worker threads. Run \`bb plugin enable workflows\`, then
|
|
1091
|
-
\`bb workflows validate|run|status|history|list|stop\`; see the \`workflows\`
|
|
1092
|
-
skill.
|
|
1093
|
-
- Memory (official, \`bb plugin install memory\`): durable cross-provider
|
|
1094
|
-
agent memory. \`bb memory catalog|search|get|add|update|forget|history\`;
|
|
1095
|
-
see the \`memory\` skill.
|
|
1096
|
-
- Docs (official, \`bb plugin install docs\`): document vaults with a
|
|
1097
|
-
pull/edit/push loop and reviewable proposals.
|
|
1098
|
-
\`bb docs vaults|list|read|pull|status|push|propose\`; see the \`docs\` skill.
|
|
1099
|
-
- Tasks (official, \`bb plugin install tasks\`): a task tracker with agent
|
|
1100
|
-
delegation. \`bb tasks show|list|comment|update|attach\`, and
|
|
1101
|
-
\`bb tasks --help\` for the rest; see the \`tasks\` skill.
|
|
1102
|
-
- Modal sandboxes (official, \`bb plugin install environment-modal-sandbox\`):
|
|
1103
|
-
reusable Modal cloud machines. \`bb modal account inspect\`,
|
|
1104
|
-
\`bb machine create --provider modal-sandbox\`, and \`bb modal image|sandbox\`;
|
|
1105
|
-
see the \`modal-sandboxes\` skill.
|
|
1106
|
-
|
|
1107
|
-
Multi-plugin repositories
|
|
1108
|
-
|
|
1109
|
-
One repository can hold several plugins, each an ordinary plugin directory
|
|
1110
|
-
with its own package.json. An optional \`.bb/plugins.json\` collection manifest
|
|
1111
|
-
indexes them:
|
|
1112
|
-
|
|
1113
|
-
{
|
|
1114
|
-
"$schema": "https://getbb.app/schemas/plugins.schema.json",
|
|
1115
|
-
"schemaVersion": 1,
|
|
1116
|
-
"name": "acme-plugins",
|
|
1117
|
-
"plugins": [
|
|
1118
|
-
{ "name": "sidebar", "source": "./plugins/sidebar" },
|
|
1119
|
-
{ "name": "status", "source": "./apps/status" }
|
|
1120
|
-
]
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
Every source is a repository-relative directory starting with "./"; absolute
|
|
1124
|
-
paths, "..", the repository root, duplicate names, and unknown fields are
|
|
1125
|
-
rejected. The file is an index only: identity, branding, entry points, and
|
|
1126
|
-
engine ranges stay in each plugin's manifest.
|
|
1127
|
-
|
|
1128
|
-
bb plugin install git:github.com/acme/repo@main --plugin sidebar
|
|
1129
|
-
bb plugin install git:github.com/acme/repo@main --subdirectory plugins/sidebar
|
|
1130
|
-
bb plugin install path:/work/repo --plugin sidebar
|
|
1131
|
-
|
|
1132
|
-
--subdirectory works without a collection manifest; --plugin resolves a name
|
|
1133
|
-
from .bb/plugins.json. When a repository with a collection manifest is not a
|
|
1134
|
-
plugin itself and neither flag is given, the install fails and lists the
|
|
1135
|
-
entry names. bb records the subdirectory, so outdated, update, and remove
|
|
1136
|
-
work per plugin.
|
|
1137
|
-
|
|
1138
|
-
Marketplaces
|
|
1139
|
-
|
|
1140
|
-
\`bb-official\` lists the plugins bundled with the app. It reads a local catalog
|
|
1141
|
-
and never uses the network; install its entries by bare name or qualified name
|
|
1142
|
-
(\`bb plugin install docs\` or \`bb plugin install docs@bb-official\`). An app
|
|
1143
|
-
update also updates the bundled copy.
|
|
1144
|
-
|
|
1145
|
-
\`bb-community\` lists reviewed plugins that live outside the app bundle, read
|
|
1146
|
-
from https://getbb.app/marketplace/v2/marketplace.json at startup and every two
|
|
1147
|
-
hours. Set BB_MARKETPLACE_URL (read at startup) to override the URL. An invalid
|
|
1148
|
-
manifest keeps the last valid catalog. \`bb plugin search\` shows install counts
|
|
1149
|
-
that bb measures through anonymous telemetry, so they undercount; third-party
|
|
1150
|
-
marketplaces have none. Builtins show "Built in", and a plugin under 25
|
|
1151
|
-
installs that was published in the last 30 days shows "New".
|
|
1152
|
-
\`bb plugin search --json\` returns the raw \`installs\`, \`installedByDefault\`,
|
|
1153
|
-
and long-form \`overview\` fields.
|
|
1154
|
-
|
|
1155
|
-
Anyone can host a third-party marketplace:
|
|
1156
|
-
|
|
1157
|
-
bb marketplace add https://plugins.acme.dev/marketplace.json
|
|
1158
|
-
bb marketplace add git:github.com/acme/bb-marketplace@main
|
|
1159
|
-
bb marketplace add git:github.com/acme/agent-plugins@main --subdirectory bb
|
|
1160
|
-
bb marketplace add path:/work/acme-marketplace
|
|
1161
|
-
|
|
1162
|
-
--subdirectory follows the same path rules as \`bb plugin install
|
|
1163
|
-
--subdirectory\`; bb reads marketplace.json and relative icons from that
|
|
1164
|
-
directory on every refresh. \`source.git.subdir\` in a catalog entry stays
|
|
1165
|
-
relative to the repository root.
|
|
1166
|
-
|
|
1167
|
-
The manifest \`name\` is the marketplace identity; duplicates and the reserved
|
|
1168
|
-
\`bb-official\` and \`bb-community\` names are refused. Install an entry of a
|
|
1169
|
-
specific marketplace with <entry-id>@<marketplace>:
|
|
1170
|
-
|
|
1171
|
-
bb plugin install thread-hover-cards@acme-plugins
|
|
1172
|
-
|
|
1173
|
-
A bare id resolves across every marketplace: one match installs, several
|
|
1174
|
-
matches fail and list the id@marketplace choices. Other source forms bypass
|
|
1175
|
-
catalog resolution. Before installing from a third-party marketplace, bb shows
|
|
1176
|
-
the marketplace, the entry's author, and the true source, including the exact
|
|
1177
|
-
release tag and commit a range lands on. \`--yes\` skips the prompt, not the
|
|
1178
|
-
resolution, and the install is refused if the listing or resolved commit
|
|
1179
|
-
changes after confirmation. Settings \u2192 Plugin marketplaces manages the same
|
|
1180
|
-
list. To publish a marketplace, see the bb-plugin-authoring skill.
|
|
1181
|
-
|
|
1182
|
-
Updates and pinning
|
|
1183
|
-
|
|
1184
|
-
Updates are manual: \`bb plugin outdated\` checks tracking sources and
|
|
1185
|
-
\`bb plugin update\` applies compatible candidates. Reinstalling an installed
|
|
1186
|
-
managed plugin is refused; use \`bb plugin update\`. A failed activation restores
|
|
1187
|
-
the previous version and leaves the failure visible.
|
|
1188
|
-
|
|
1189
|
-
Exact npm versions, Git tags and commits, path sources, and bundled official
|
|
1190
|
-
plugins are pinned. npm ranges, dist-tags, and omitted specs, omitted Git refs
|
|
1191
|
-
(the default branch), Git branches, and Git semver ranges track compatible
|
|
1192
|
-
updates. Change a pinned git:/npm: source with \`bb plugin remove\` (which
|
|
1193
|
-
deletes settings, secrets, and schedules) and a fresh install. Edit a local
|
|
1194
|
-
path plugin in place and \`bb plugin reload <id>\`, or move it with
|
|
1195
|
-
\`bb plugin install path:<new dir>\`; both keep its configuration.
|
|
1196
|
-
|
|
1197
|
-
Managed git:/npm: installs refuse engines.bb and engines.bbPluginSdk
|
|
1198
|
-
mismatches, manifest and artifact identity mismatches, and ids reserved by
|
|
1199
|
-
bundled plugins. Git and path installs build the plugin on install (git
|
|
1200
|
-
sources need \`git\`; bb ships its own npm), and a build failure fails the
|
|
1201
|
-
install. npm packages must ship their prebuilt app and host bundles.
|
|
1202
|
-
|
|
1203
|
-
Git semver ranges
|
|
1204
|
-
|
|
1205
|
-
A git source can track releases over the repository's tags:
|
|
1206
|
-
|
|
1207
|
-
bb plugin install git:github.com/acme/repo@^1.2.0
|
|
1208
|
-
bb plugin install git:github.com/acme/repo@semver:^1.2.0
|
|
1209
|
-
bb plugin install git:github.com/acme/repo@^1.2.0 --tag-prefix notes/
|
|
1210
|
-
|
|
1211
|
-
bb keeps tags named [<tag-prefix>]vX.Y.Z and installs the highest one the
|
|
1212
|
-
range allows. Prereleases are excluded unless the range names one. Without
|
|
1213
|
-
--tag-prefix tags are repository-wide (v1.2.3); with it they version one
|
|
1214
|
-
plugin (notes/v1.2.3).
|
|
1215
|
-
|
|
1216
|
-
bb records the selected tag and its commit. If that tag later points at
|
|
1217
|
-
another commit, bb refuses it and names both commits; remove and reinstall
|
|
1218
|
-
the plugin to accept the new commit.
|
|
1219
|
-
|
|
1220
|
-
A bare spec that reads as a range (\`^1.2.0\`, \`1.x\`, \`>=1 <2\`) resolves over
|
|
1221
|
-
tags only when no branch or tag has that literal name; when one does, the
|
|
1222
|
-
install fails and asks you to choose \`@semver:<range>\` or \`@ref:<name>\`. Bare
|
|
1223
|
-
version tags such as \`v1\` and \`v1.2.3\` are always the literal tag.
|
|
1224
|
-
|
|
1225
|
-
Authoring a plugin
|
|
1226
|
-
|
|
1227
|
-
bb plugin new <name> Scaffold ./bb-plugin-<name> (backend, sidebar
|
|
1228
|
-
page, \`bb <name>\` command, skill) and install
|
|
1229
|
-
its npm dependencies; no server required
|
|
1230
|
-
bb plugin install . Register the directory in place
|
|
1231
|
-
bb plugin dev [path] Watch sources, rebuild, and reload the
|
|
1232
|
-
installed plugin on every save
|
|
1233
|
-
bb plugin build [path] Compile the plugin into dist/; no server
|
|
1234
|
-
required
|
|
1235
|
-
bb plugin types [path] [--check] Sync the plugin's SDK and shimmed-package
|
|
1236
|
-
type pins to this bb; --check only reports
|
|
1237
|
-
bb plugin migrate [path] [--yes] Move a plugin that vendors types/ to the
|
|
1238
|
-
@get-bb/plugin-sdk npm package
|
|
1239
|
-
|
|
1240
|
-
The full authoring reference (manifest, every API surface, build and release,
|
|
1241
|
-
testing, and marketplace publishing) is the built-in \`bb-plugin-authoring\`
|
|
1242
|
-
skill; in a checkout it lives under plugins/bb-guide/skills/bb-plugin-authoring/.
|
|
1243
|
-
\`plugins/\` holds every bundled plugin and \`examples/plugins/\` holds reference
|
|
1244
|
-
plugins.
|
|
1245
|
-
|
|
1246
|
-
## Inspect plugin RPC
|
|
1247
|
-
|
|
1248
|
-
\`bb plugin rpc list [plugin-id] [--method <exact-name>] [--json]\` lists discoverable methods from running plugins, optionally restricted to one plugin. \`bb plugin rpc inspect <plugin-id> [method] [--json]\` dumps registration and method descriptions plus input/output JSON Schemas. Copy the relevant schema into your consumer and call the existing plugin RPC endpoint. Discovery is opt-in advertising, not access control; method names may carry versions such as \`provider-usage.v1.listResources\`.
|
|
1249
|
-
|
|
1250
|
-
\`bb plugin rpc call <plugin-id> <method> [--input-file <json-path>] [--json]\` invokes a method using server-side schema validation. Omitting the input file sends JSON null. Input files avoid putting sensitive values in command arguments. Handler refusals print their code and message and exit non-zero: \`forbidden\` (403), \`not_found\` (404), \`conflict\` (409), or \`invalid\` (422).
|
|
1251
|
-
|
|
1252
|
-
### Background updates
|
|
1253
|
-
|
|
1254
|
-
\`bb plugin update <id> --yes\` starts a server job and waits by polling, so the activation stability check does not hold one HTTP request open. Add \`--no-wait\` to return immediately. Use \`bb plugin update-jobs [job-id] --json\` for progress and results, including automatic rollback. Queued/running updates continue after the CLI or app disconnects. Finished jobs remain for ten minutes; jobs do not survive server restarts. Running updates cannot be cancelled midway through activation.
|
|
1255
|
-
|
|
1256
|
-
SDK: \`plugins.applyUpdate({ pluginId })\` waits; \`plugins.experimental_startUpdate({ pluginId })\` returns the job. Inspect with \`plugins.experimental_updateJobs.list()\` or \`.get({ jobId })\`. Raw HTTP callers opt in with \`Prefer: respond-async\`; legacy callers still receive the completed result.`,variables:{}},{id:"bbGuideProjects",body:`Project commands
|
|
1257
|
-
|
|
1258
|
-
A project maps to a code repository. All threads belong to a project.
|
|
1259
|
-
|
|
1260
|
-
bb project list List ordinary projects
|
|
1261
|
-
--include-personal Also include the personal project
|
|
1262
|
-
bb project discover Find recently used git repos
|
|
1263
|
-
--machine <id-or-name> Machine to scan (default: local)
|
|
1264
|
-
--host <id-or-name> Alias for --machine
|
|
1265
|
-
bb project history <id> List prompt history
|
|
1266
|
-
bb project reorder <id> Reorder in the sidebar
|
|
1267
|
-
--after <id> Previous project, or omit for start
|
|
1268
|
-
--before <id> Next project, or omit for end
|
|
1269
|
-
bb project create --name "..." [options]
|
|
1270
|
-
--root <path> Project source path
|
|
1271
|
-
--machine <id-or-name> Bind the path to a connected machine
|
|
1272
|
-
--host <id-or-name> Alias for --machine
|
|
1273
|
-
|
|
1274
|
-
An explicit machine/host selector accepts an exact ID or unambiguous name and
|
|
1275
|
-
binds --root to that machine. Omitting the selector preserves the existing
|
|
1276
|
-
local CLI machine fallback (normally the server machine).
|
|
1277
|
-
|
|
1278
|
-
bb project show <id> Show project details
|
|
1279
|
-
Accepts proj_personal to inspect Personal.
|
|
1280
|
-
bb project update <id> Update a project
|
|
1281
|
-
--name <name> New name
|
|
1282
|
-
|
|
1283
|
-
bb project delete <id> Delete project and all threads
|
|
1284
|
-
--yes Skip confirmation
|
|
1285
|
-
|
|
1286
|
-
Global prompt history:
|
|
1287
|
-
|
|
1288
|
-
bb prompt-history list [--cursor <cursor>] [--limit <number>]
|
|
1289
|
-
|
|
1290
|
-
Lists accepted prompts across projects and threads newest first. Pass the
|
|
1291
|
-
returned cursor to continue from the next page.
|
|
1292
|
-
|
|
1293
|
-
Discovery:
|
|
1294
|
-
|
|
1295
|
-
bb project branches <id> --host <id> List branches for a machine source
|
|
1296
|
-
bb project paths <id> Search workspace paths
|
|
1297
|
-
bb project files <id> List workspace files
|
|
1298
|
-
bb project content <id> <path> Read file content (binary is base64;
|
|
1299
|
-
--json reports contentEncoding)
|
|
1300
|
-
bb project commands <id> --provider <id>
|
|
1301
|
-
List commands and skills
|
|
1302
|
-
--machine <id-or-name> Target project source machine
|
|
1303
|
-
--host <id-or-name> Alias for --machine
|
|
1304
|
-
--environment <id> Target environment workspace
|
|
1305
|
-
|
|
1306
|
-
The machine/host and environment selectors are mutually exclusive. An
|
|
1307
|
-
environment selects its owning machine and workspace; otherwise an explicit
|
|
1308
|
-
machine selects that machine's project source. Omitting both intentionally
|
|
1309
|
-
falls back to the server machine's project source.
|
|
1310
|
-
|
|
1311
|
-
Personal file access (\`paths\`, \`files\`, \`content\`) requires an explicit
|
|
1312
|
-
--environment <id> belonging to Personal. Personal has no default project
|
|
1313
|
-
source; the selected environment must be ready.
|
|
1314
|
-
|
|
1315
|
-
Path and file searches honor Git ignore rules, including local and global
|
|
1316
|
-
exclusions; tracked and non-ignored untracked files, including hidden files,
|
|
1317
|
-
remain searchable. Non-Git workspaces use filesystem listings. Use
|
|
1318
|
-
\`bb file list|paths\` for listings that include ignored files.
|
|
1319
|
-
|
|
1320
|
-
Attachments:
|
|
1321
|
-
|
|
1322
|
-
bb project attachment upload <id> Upload bytes from the CLI machine
|
|
1323
|
-
--client-file <path> Path read on this CLI machine
|
|
1324
|
-
--filename <name> Attachment filename override
|
|
1325
|
-
--mime-type <type> MIME override (otherwise inferred)
|
|
1326
|
-
bb project attachment download <id> <attachment-path>
|
|
1327
|
-
--client-file <path> Destination on this CLI machine
|
|
1328
|
-
|
|
1329
|
-
Uploads use multipart bytes and return a server-managed attachment DTO. Pass
|
|
1330
|
-
its relative \`path\` to thread --file/--image input. Thread --file and --image
|
|
1331
|
-
upload absolute paths and file: URLs from the CLI machine automatically;
|
|
1332
|
-
relative values remain existing server attachment paths.
|
|
1333
|
-
image/* uploads are limited to 10MB; other files are limited to 25MB.
|
|
1334
|
-
image/heic and image/heif uploads are rejected because no renderer or
|
|
1335
|
-
provider can decode them; convert them to JPEG or PNG first. There is no
|
|
1336
|
-
command to list or remove project attachments.
|
|
1337
|
-
|
|
1338
|
-
Sources:
|
|
1339
|
-
|
|
1340
|
-
Projects can have multiple machine-local path sources.
|
|
1341
|
-
|
|
1342
|
-
bb project source add <projectId> Add a source
|
|
1343
|
-
--path <path> Local path
|
|
1344
|
-
--clone Clone the project's Git remote
|
|
1345
|
-
--remote-url <url> Git remote override for --clone
|
|
1346
|
-
--target-path <path> Destination override for --clone
|
|
1347
|
-
--machine <id-or-name> Target machine (--host is an alias)
|
|
1348
|
-
--default Set as default source
|
|
1349
|
-
|
|
1350
|
-
Explicit project source selectors must name a connected machine. Omitting
|
|
1351
|
-
the selector preserves the same local CLI machine fallback as project create.
|
|
1352
|
-
|
|
1353
|
-
bb project source update <projectId> <sourceId>
|
|
1354
|
-
--path <path>
|
|
1355
|
-
--default
|
|
1356
|
-
|
|
1357
|
-
bb project source delete <projectId> <sourceId>
|
|
1358
|
-
|
|
1359
|
-
A live project must retain at least one source; a project pending deletion
|
|
1360
|
-
may remove its last source.`,variables:{}},{id:"bbGuideProviders",body:`Provider commands
|
|
1361
|
-
|
|
1362
|
-
Providers are agent backends (e.g., codex, claude-code). Each supports different models.
|
|
1363
|
-
|
|
1364
|
-
bb provider list [--machine <id-or-name> | --environment <id>]
|
|
1365
|
-
List available providers
|
|
1366
|
-
bb provider models [providerId] [--machine <id-or-name> | --environment <id>]
|
|
1367
|
-
[--project <id>]
|
|
1368
|
-
List models for a provider
|
|
1369
|
-
|
|
1370
|
-
Use these before spawning threads if you are unsure which provider or model to use.
|
|
1371
|
-
\`--host\` is an alias for \`--machine\`. Machine and environment selectors are
|
|
1372
|
-
mutually exclusive because an environment already selects its machine. When no
|
|
1373
|
-
selector is supplied, both commands intentionally inspect the server machine.
|
|
1374
|
-
\`bb guide threads\` describes how \`bb thread spawn\` picks a default provider and
|
|
1375
|
-
model.
|
|
1376
|
-
|
|
1377
|
-
Some providers read their models and options from the directory they run in
|
|
1378
|
-
(Pi, and opencode's project-level agents, for example). \`--environment\` lists
|
|
1379
|
-
what the provider reports in that environment's directory. \`--project\` lists
|
|
1380
|
-
what it reports in the project's checkout on the chosen machine, which is what
|
|
1381
|
-
a new thread in that project is offered; it cannot be combined with
|
|
1382
|
-
\`--environment\`. Other providers answer the same for every directory.
|
|
1383
|
-
|
|
1384
|
-
When a provider's models declare options (a mode, an on/off switch), \`bb provider
|
|
1385
|
-
models\` lists them under the table with their ids, values and defaults; \`--json\`
|
|
1386
|
-
carries them per model as \`sessionOptions\`. Choose values at creation with
|
|
1387
|
-
\`bb thread spawn --option <id>=<value>\` and on an existing thread with
|
|
1388
|
-
\`bb thread options --set <id>=<value>\`. A model may accept only some values
|
|
1389
|
-
(\`fixed: true\` on an on/off option, or a shorter \`values\` list): a spawn
|
|
1390
|
-
without \`--model\` starts on a model that fits the chosen options, and a spawn
|
|
1391
|
-
whose \`--model\` cannot run with them is refused with the name of one that can.
|
|
1392
|
-
|
|
1393
|
-
Service tiers are provider-defined ids. \`bb provider list --json\` reports each
|
|
1394
|
-
provider's \`serviceTiers\` ({id, label, description?}); \`default\` always means
|
|
1395
|
-
the provider's standard tier. A model may narrow that list: \`bb provider
|
|
1396
|
-
models\` shows a Service tiers column, and \`--json\` reports
|
|
1397
|
-
\`supportedServiceTiers\` per model (absent when the provider does not report
|
|
1398
|
-
tiers per model, in which case the model accepts every tier the provider
|
|
1399
|
-
lists). Pass a tier id to \`--service-tier\`; a tier the provider does not list
|
|
1400
|
-
is rejected.
|
|
1401
|
-
|
|
1402
|
-
Model lists answer from the machine's last stored list while a background
|
|
1403
|
-
refresh runs, so a list can be hours old. A provider whose refresh keeps
|
|
1404
|
-
failing or timing out keeps answering from its last stored list.
|
|
1405
|
-
|
|
1406
|
-
When no list can be served, bb provider models prints the failing provider,
|
|
1407
|
-
the failure code, and the underlying host message on stderr, then reports the
|
|
1408
|
-
empty catalog on stdout. The model pickers show the same underlying message
|
|
1409
|
-
beneath their summary line.
|
|
1410
|
-
|
|
1411
|
-
Enabling and disabling providers
|
|
1412
|
-
|
|
1413
|
-
Manage agents in Settings \u2192 Providers. Install provider plugins in Settings \u2192
|
|
1414
|
-
Plugins.
|
|
1415
|
-
|
|
1416
|
-
bb provider disable <id>
|
|
1417
|
-
bb provider enable <id>
|
|
1418
|
-
bb provider list --all
|
|
1419
|
-
|
|
1420
|
-
Disable hides one provider from pickers and the ordinary list and rejects new
|
|
1421
|
-
sessions and turns. It preserves its CLI, plugin, siblings and thread history;
|
|
1422
|
-
in-flight turns can finish. Enable also enables its supplying plugin if needed,
|
|
1423
|
-
while preserving other providers' individual opt-outs. list --all shows the global
|
|
1424
|
-
catalog including disabled plugins, without machine/environment selectors.
|
|
1425
|
-
SDK: providers.catalog() and providers.setEnabled({ providerId, enabled }).
|
|
1426
|
-
Enable restores automatic discovery, so installed-only agents again appear only
|
|
1427
|
-
where their CLI is installed. Disabling the default clears its selection; new
|
|
1428
|
-
threads use the next enabled provider in saved order, including in projects whose
|
|
1429
|
-
last-used provider is disabled. Explicit or existing-thread choices never
|
|
1430
|
-
silently switch.
|
|
1431
|
-
|
|
1432
|
-
Provider-native memory can be controlled on the separate Settings \u2192 Providers
|
|
1433
|
-
\u2192 Codex and Settings \u2192 Providers \u2192 Claude Code pages. Codex memory controls
|
|
1434
|
-
both recall (\`memories.use_memories\`) and future generation
|
|
1435
|
-
(\`memories.generate_memories\`). Claude Code memory controls native auto-memory
|
|
1436
|
-
reads and writes (\`autoMemoryEnabled\`). Both preferences default on and apply
|
|
1437
|
-
when a provider thread is started, resumed, or forked; they do not interrupt
|
|
1438
|
-
an active turn. These settings are separate from bb's optional Memory plugin,
|
|
1439
|
-
an official plugin bundled with the app.
|
|
1440
|
-
|
|
1441
|
-
Provider-native subagents can also be disabled on those provider pages: Codex
|
|
1442
|
-
loses its native multi-agent feature and Claude Code its native Task tool. The preferences default off and apply
|
|
1443
|
-
when a provider thread is started, resumed, or forked; they do not modify the
|
|
1444
|
-
provider's global configuration.
|
|
1445
|
-
|
|
1446
|
-
Claude Code's native Workflow tool can be disabled separately on its provider
|
|
1447
|
-
page. This preference also defaults off and applies to newly started, resumed,
|
|
1448
|
-
or forked provider sessions. Claude Code plugin settings (\`disable1MContext\`,
|
|
1449
|
-
\`chromeEnabled\`, \`artifactsEnabled\`, \`sandboxEnabled\`) are set with
|
|
1450
|
-
\`bb plugin config provider-claude-code set <key> <value>\` and documented in the
|
|
1451
|
-
claude-code-provider skill.
|
|
1452
|
-
|
|
1453
|
-
Automatic retries after provider overloads, server or connection errors, and
|
|
1454
|
-
subscription-window limits come from the bundled Provider retry plugin
|
|
1455
|
-
(\`bb provider-retry status\`); see \`bb guide plugins\`. For a manual retry of a
|
|
1456
|
-
failed turn, use \`bb thread retry\`.
|
|
1457
|
-
|
|
1458
|
-
Known ACP agents can appear automatically when their CLI is installed on the
|
|
1459
|
-
host. For example, opencode, omp, Grok Build's grok CLI, or Hermes' hermes CLI
|
|
1460
|
-
on PATH appears as provider acp-opencode, acp-omp, acp-grok, or
|
|
1461
|
-
acp-hermes-agent. The acp-provider skill covers OpenCode launch settings,
|
|
1462
|
-
OpenCode Go usage, and per-agent compaction support.
|
|
1463
|
-
|
|
1464
|
-
bb indexes the native user and project skill roots for Codex, Claude Code, Pi,
|
|
1465
|
-
Cursor, OpenCode, omp, Grok Build, and Hermes Agent. This includes compatibility
|
|
1466
|
-
roots such as .agents/skills and .claude/skills when the provider supports them.
|
|
1467
|
-
It also includes project ancestor roots for providers that search to the Git
|
|
1468
|
-
repository root. Configured Pi, omp, Grok, and Hermes directories are included.
|
|
1469
|
-
Enabled provider plugins also contribute skills to the selected provider's \`/\`
|
|
1470
|
-
command menu. \`bb skill list\` shows native skills for Claude Code, Codex, and
|
|
1471
|
-
Cursor.
|
|
1472
|
-
|
|
1473
|
-
ACP agents (acp-*), including custom agents set in the ACP providers plugin's
|
|
1474
|
-
customAgents setting, are documented in the acp-provider skill.
|
|
1475
|
-
|
|
1476
|
-
Top-level customModels in the app data-dir config.json adds extra picker
|
|
1477
|
-
entries. Each entry has a providerId (a built-in provider id or any acp-*
|
|
1478
|
-
provider id), a model id, and an optional displayName. bb skips an invalid
|
|
1479
|
-
entry with a warning. The entry then appears in bb provider models output and
|
|
1480
|
-
in the model picker, but the provider must still accept the id: claude-code
|
|
1481
|
-
and codex accept unlisted ids, while an ACP agent can reject an id it does
|
|
1482
|
-
not know at session start. OpenCode rejects unlisted ids, so add an OpenCode
|
|
1483
|
-
model to the OpenCode config instead. Edit the JSON and run bb-app config
|
|
1484
|
-
refresh; there is no set/unset CLI surface. The streamerMode
|
|
1485
|
-
General setting hides every entry from these lists; see the customization
|
|
1486
|
-
chapter.
|
|
1487
|
-
|
|
1488
|
-
Use top-level sharedSkillRoots for one provider-neutral skill collection. The
|
|
1489
|
-
user and project paths use the same relative-path rules. bb indexes these roots
|
|
1490
|
-
as read-only sources. It then injects the selected skills into all providers.
|
|
1491
|
-
The bb user and project roots keep higher precedence than matching shared roots.`,variables:{}},{id:"bbGuideTerminals",body:`Terminal commands
|
|
1492
|
-
|
|
1493
|
-
Use terminals for long-running commands that should stay alive for the user,
|
|
1494
|
-
such as dev servers, watch tasks, REPLs, and database consoles. A terminal is a
|
|
1495
|
-
real persistent PTY and appears in the bb UI.
|
|
1496
|
-
|
|
1497
|
-
List and create require exactly one explicit scope:
|
|
1498
|
-
|
|
1499
|
-
bb terminal list --thread <thread-id>
|
|
1500
|
-
bb terminal list --environment <environment-id>
|
|
1501
|
-
bb terminal list --machine <id-or-name> [--cwd <path>]
|
|
1502
|
-
|
|
1503
|
-
bb terminal create --thread <thread-id> --command "pnpm dev"
|
|
1504
|
-
bb terminal create --environment <environment-id>
|
|
1505
|
-
bb terminal create --machine <id-or-name> [--cwd <path>] (alias: start)
|
|
1506
|
-
--host <id-or-name> Alias for --machine
|
|
1507
|
-
--title <title> Display title
|
|
1508
|
-
--id <terminal-id> Use this ID (term_ plus 10 characters); fails if it exists
|
|
1509
|
-
--cols <n> Initial terminal columns
|
|
1510
|
-
--rows <n> Initial terminal rows
|
|
1511
|
-
--attach Attach after creating
|
|
1512
|
-
--json Print machine-readable output
|
|
1513
|
-
|
|
1514
|
-
Machine names are resolved to an explicit machine ID. No scope defaults to the
|
|
1515
|
-
server machine, and --cwd is valid only with --machine or --host.
|
|
1516
|
-
|
|
1517
|
-
A terminal runs the machine's own shell: $SHELL (then zsh, bash, sh) on macOS
|
|
1518
|
-
and Linux; on Windows, PowerShell 7 when \`pwsh\` is on PATH, otherwise Windows
|
|
1519
|
-
PowerShell, otherwise cmd. Write --command in that shell's syntax. To run a
|
|
1520
|
-
program with arguments without knowing the shell, pass them after \`--\`
|
|
1521
|
-
(\`bb terminal create --thread <id> -- pnpm test "my file.ts"\`): the machine
|
|
1522
|
-
quotes each argument for its own shell. \`send --enter\` presses Enter (a carriage
|
|
1523
|
-
return), which every one of those shells accepts. The terminal's exit code is
|
|
1524
|
-
the command's own exit code on every shell.
|
|
1525
|
-
|
|
1526
|
-
All other operations need only the terminal ID. They also accept the scope
|
|
1527
|
-
flags above and ignore them, so a command built for \`list\` or \`create\` still
|
|
1528
|
-
runs:
|
|
1529
|
-
|
|
1530
|
-
bb terminal show <terminal-id>
|
|
1531
|
-
bb terminal attach <terminal-id> Ctrl-B d detaches
|
|
1532
|
-
bb terminal send <terminal-id> --text <text> [--enter]
|
|
1533
|
-
--stdin Read bytes from stdin instead of --text
|
|
1534
|
-
bb terminal resize <terminal-id> --cols <n> --rows <n>
|
|
1535
|
-
bb terminal rename <terminal-id> <title>
|
|
1536
|
-
bb terminal restart <terminal-id> Atomically replaces it with a shell; does not replay the original command
|
|
1537
|
-
bb terminal close <terminal-id> [--if-clean] (alias: stop)
|
|
1538
|
-
|
|
1539
|
-
bb terminal output <terminal-id>
|
|
1540
|
-
--since-seq <n> Read output chunks from a sequence
|
|
1541
|
-
--tail-bytes <n> Bound output to latest N bytes
|
|
1542
|
-
--limit-chunks <n> Bound output to latest N chunks
|
|
1543
|
-
--json Print chunks, nextSeq, truncated, status, exitCode, and closeReason
|
|
1544
|
-
|
|
1545
|
-
Output stays readable after the command exits: the machine keeps a finished
|
|
1546
|
-
terminal's scrollback for 30 minutes, until its daemon restarts, or until many
|
|
1547
|
-
newer terminals have exited. For an exited terminal the output is followed by
|
|
1548
|
-
\`Terminal <id> exited with code N\` on stderr. Once the scrollback is gone,
|
|
1549
|
-
output fails with \`terminal_output_unavailable\` and says why.
|
|
1550
|
-
|
|
1551
|
-
bb terminal wait <terminal-id>
|
|
1552
|
-
--contains <text> Wait for new output containing text
|
|
1553
|
-
--regex <pattern> Wait for new output matching regex
|
|
1554
|
-
--exit Wait until the terminal exits
|
|
1555
|
-
--from-start Include existing scrollback
|
|
1556
|
-
--timeout <duration> Seconds, or a duration with a unit: 90s, 5m (default: 30s)
|
|
1557
|
-
--poll-interval <duration> Milliseconds, or a duration with a unit (default: 500ms)
|
|
1558
|
-
|
|
1559
|
-
When the terminal exits before the text appears, wait stops at once with exit
|
|
1560
|
-
code 124, the terminal's exit code, and the last output it printed. \`--exit\`
|
|
1561
|
-
prints the exit code.
|
|
1562
|
-
|
|
1563
|
-
For a dev server, prefer:
|
|
1564
|
-
|
|
1565
|
-
bb terminal create --thread <thread-id> --title "pnpm dev" --command "pnpm dev"
|
|
1566
|
-
bb terminal wait <terminal-id> --contains "Local:" --timeout 120
|
|
1567
|
-
|
|
1568
|
-
Do not run long-lived servers as one-off foreground commands when the user will
|
|
1569
|
-
need to inspect logs, refresh the page, or stop the process later.`,variables:{}},{id:"bbGuideThreadInspection",body:`Thread inspection
|
|
1570
|
-
|
|
1571
|
-
Read-only commands take a thread ID or --self where supported.
|
|
1572
|
-
|
|
1573
|
-
Listing:
|
|
1574
|
-
|
|
1575
|
-
bb thread list List threads
|
|
1576
|
-
--project <id> Filter by project
|
|
1577
|
-
--environment <id> Filter by environment
|
|
1578
|
-
--machine <id-or-name> Filter by the machine the environment is on (alias --host)
|
|
1579
|
-
--parent-thread <id> Filter by parent thread
|
|
1580
|
-
--thread <id> Only this thread; unknown or deleted IDs are left out (repeatable, up to 200)
|
|
1581
|
-
--archived Show only archived threads
|
|
1582
|
-
--section <id> Filter by section
|
|
1583
|
-
--unsectioned Show only threads outside sections
|
|
1584
|
-
--include-hidden Include hidden threads
|
|
1585
|
-
|
|
1586
|
-
The table prints ID, Title, Project, and Status. Title uses the thread
|
|
1587
|
-
title, then the fallback title from the first prompt, then "-". Long
|
|
1588
|
-
titles are cut at 60 characters. Project shows the project name; the
|
|
1589
|
-
personal project shows "-". Use --json for the full thread records.
|
|
1590
|
-
|
|
1591
|
-
bb thread search <query> [--limit <1-50>]
|
|
1592
|
-
Search threads and messages
|
|
1593
|
-
bb thread history <id> List prompt history
|
|
1594
|
-
|
|
1595
|
-
bb thread count Count threads without listing them
|
|
1596
|
-
--status <status> Count threads in this status: pending, idle, starting, active, stopping, error
|
|
1597
|
-
--host <id> Count threads whose environment is on this machine
|
|
1598
|
-
--provider <id> Count threads running on this provider
|
|
1599
|
-
--project <id> Count threads in this project
|
|
1600
|
-
--parent <id|none> Count one thread's children, or 'none' for threads with no parent
|
|
1601
|
-
--by <dimension> Group the count by host, provider, or project
|
|
1602
|
-
|
|
1603
|
-
Counting happens in the database, so use it instead of listing threads and
|
|
1604
|
-
counting rows: \`bb thread list\` pages a bounded window and would miscount
|
|
1605
|
-
(SDK: \`threads.count({ status, hostId, providerId, projectId, parentThreadId, groupBy })\`).
|
|
1606
|
-
Archived, deleted, and hidden threads are excluded. Without --by the command
|
|
1607
|
-
prints one number; with --by it prints a count per group (threads with no
|
|
1608
|
-
host/provider/project group under "-") followed by the total.
|
|
1609
|
-
|
|
1610
|
-
Sections:
|
|
1611
|
-
|
|
1612
|
-
bb thread section list
|
|
1613
|
-
bb thread section create <name>
|
|
1614
|
-
bb thread section rename <id> <name>
|
|
1615
|
-
bb thread section delete <id> [--yes]
|
|
1616
|
-
|
|
1617
|
-
Inspecting:
|
|
1618
|
-
|
|
1619
|
-
bb thread context [id] Show recorded context usage and available breakdown (--self, --json)
|
|
1620
|
-
bb thread commands [id] List the slash commands the thread's agent has advertised (--self, --json)
|
|
1621
|
-
bb thread options [id] List the session options the agent reports, with current values (--self, --json)
|
|
1622
|
-
--set <option=value> Choose a value, applied on the thread's next turn (repeatable)
|
|
1623
|
-
--clear <option> Drop a choice that has not been applied yet (repeatable)
|
|
1624
|
-
bb thread show [id] Show thread details and pull request status
|
|
1625
|
-
--self Target current thread
|
|
1626
|
-
--work-status Include git working-tree status
|
|
1627
|
-
--git-diff Include git diff
|
|
1628
|
-
--diff-target <type> Diff scope: uncommitted, branch_committed, all, commit
|
|
1629
|
-
--diff-sha <sha> Commit SHA (for --diff-target commit)
|
|
1630
|
-
--diff-merge-base <branch> Override merge-base branch for diff
|
|
1631
|
-
|
|
1632
|
-
Shows pull request status for the attached environment branch when available.
|
|
1633
|
-
|
|
1634
|
-
\`thread context\` reads the latest stored context measurement without starting
|
|
1635
|
-
a provider request; \`--json\` prints \`{ usage: ... }\` (\`null\` when unavailable).
|
|
1636
|
-
Claude Code includes an estimated breakdown when available; other providers
|
|
1637
|
-
report totals. When the provider reports the session's cumulative cost,
|
|
1638
|
-
\`usage.cost\` is \`{ amount, currency }\`. With the \`compactExpiredCache\`
|
|
1639
|
-
experiment on, \`usage.compactionOfferAt\` is when the provider's prompt cache
|
|
1640
|
-
for this context expires (Claude Code and Pi report cache lifetimes); after
|
|
1641
|
-
it, \`bb thread tell --compact-first\` avoids re-reading the context uncached.
|
|
1642
|
-
|
|
1643
|
-
\`thread commands\` lists the slash commands advertised for the current
|
|
1644
|
-
session; ACP agents and Claude Code report these live, so the list is empty
|
|
1645
|
-
until the agent sends one. \`bb project commands\` also lists Claude Code's
|
|
1646
|
-
commands before a thread starts. \`thread options --set\` takes \`true\` or \`false\` for an on/off
|
|
1647
|
-
option; \`bb provider models <provider>\` lists the options a model declares.
|
|
1648
|
-
|
|
1649
|
-
bb thread log [id] Show thread event log
|
|
1650
|
-
--self Target current thread
|
|
1651
|
-
--format <format> Output format: json, minimal, verbose
|
|
1652
|
-
--limit <count> Max entries: events for json (oldest first, default 100);
|
|
1653
|
-
user-message turns for minimal/verbose (newest first, default 20, max 100)
|
|
1654
|
-
--after-seq <seq> Paginate after sequence number (json only)
|
|
1655
|
-
--all Print the whole thread, paging through every entry
|
|
1656
|
-
--message <seq> Print one message
|
|
1657
|
-
--context <count> With --message, also print this many messages around it (max 20)
|
|
1658
|
-
|
|
1659
|
-
Human formats end with a notice when older history was omitted; --json warns
|
|
1660
|
-
on stderr when more events exist beyond the printed page. Human-format --all
|
|
1661
|
-
walks a consistent history snapshot and joins paginated group contents.
|
|
1662
|
-
Appends stay outside that walk; rerun the command if a history edit invalidates it.
|
|
1663
|
-
|
|
1664
|
-
bb thread output [id] Get the final output of a thread
|
|
1665
|
-
--self Target current thread
|
|
1666
|
-
|
|
1667
|
-
bb thread wait <id> Wait for a thread status or event (defaults to --status idle)
|
|
1668
|
-
--status <status> Wait for this status
|
|
1669
|
-
--event <type> Wait for this event type
|
|
1670
|
-
--timeout <duration> Seconds, or a duration with a unit: 90s, 20m, 4h (default: 1200s / 20 min)
|
|
1671
|
-
--poll-interval <duration> Milliseconds, or a duration with a unit
|
|
1672
|
-
|
|
1673
|
-
Opening threads and files in the app:
|
|
1674
|
-
|
|
1675
|
-
In chat, reference a thread as @thread:thr_abc123, substituting its actual ID.
|
|
1676
|
-
BB renders the correct project-aware link; do not construct thread URLs manually.
|
|
1677
|
-
(Pasting a bb thread URL into the app composer converts it to the same mention;
|
|
1678
|
-
CLI prompts are not converted, so use @thread:<id>.)
|
|
1679
|
-
Reference one message as @thread:thr_abc123#msg=42, taking the number from
|
|
1680
|
-
sourceSeq in \`bb thread search --json\`. Read it, or a copied message link
|
|
1681
|
-
(\u2026/threads/thr_abc123#msg=42), with \`bb thread log thr_abc123 --message 42\`.
|
|
1682
|
-
|
|
1683
|
-
bb thread open <path> Open a file in the current BB thread panel
|
|
1684
|
-
bb thread open <thread-id> [path] Open a thread, optionally with a panel file
|
|
1685
|
-
--line <number> Line number to focus
|
|
1686
|
-
--split <placement> right, down, left, top, or replace (default)
|
|
1687
|
-
bb thread pane <action> [thread-id] Maximize, restore, toggle, spotlight, or clear spotlight
|
|
1688
|
-
|
|
1689
|
-
Inside a BB thread, BB_THREAD_ID selects the current thread automatically and
|
|
1690
|
-
the thread ID argument is omitted for file-only opens. Outside a BB thread,
|
|
1691
|
-
pass the thread ID as the first argument. A thread already open in a pane is focused instead of
|
|
1692
|
-
duplicated. Edge placement creates panes through the eighth pane; at eight
|
|
1693
|
-
panes, it replaces the focused pane.
|
|
1694
|
-
Pane actions broadcast to connected BB app windows and affect the matching
|
|
1695
|
-
already-open pane without changing its split tree, and report how many
|
|
1696
|
-
clients received the action (SDK: \`threads.paneAction({ threadId, action })\`).
|
|
1697
|
-
Spotlight focuses that
|
|
1698
|
-
pane and dims the others; clear-spotlight focuses it and removes split dimming.
|
|
1699
|
-
The app command \`pane.maximize.toggle\` (default \`Mod+Shift+E\`) maximizes or
|
|
1700
|
-
restores the focused split pane and can be rebound with \`bb settings keyboard set\`.
|
|
1701
|
-
Paths can be thread-relative workspace paths, or absolute paths inside the
|
|
1702
|
-
target thread workspace. Absolute paths under BB_THREAD_STORAGE open as
|
|
1703
|
-
thread-storage files for the current thread. Use this for Markdown or HTML
|
|
1704
|
-
artifacts you create for the user so they open in the BB IDE.
|
|
1705
|
-
|
|
1706
|
-
Persisted panel tabs:
|
|
1707
|
-
|
|
1708
|
-
bb thread tabs show <thread-id>
|
|
1709
|
-
bb thread tabs set <thread-id> --expected-revision <n> --tabs-json '<json>'
|
|
1710
|
-
|
|
1711
|
-
Core Info and Diff use plugin id \`core\` and tab ids \`info\` and \`diff\`. Legacy \`thread-info\` and \`git-diff\` entries convert automatically without changing their order.
|
|
1712
|
-
|
|
1713
|
-
Pinned plugin tabs use \`{ "id": "plugin-fixed:<plugin-id>:<tab-id>", "kind": "plugin-fixed", "pluginId": "<plugin-id>", "tabId": "<tab-id>" }\`.
|
|
1714
|
-
The id encodes each plugin/tab id with percent escapes. The app shows registered,
|
|
1715
|
-
visible tabs and retains saved identities while plugins are hidden or disabled.
|
|
1716
|
-
The SDK uses \`threads.tabs.get({ threadId })\` and
|
|
1717
|
-
\`threads.tabs.update({ threadId, expectedRevision, tabs })\` for the same state.
|
|
1718
|
-
Selection stays local to each client. Plugin authors can find registration and
|
|
1719
|
-
navigation details in the Plugin Guide's Thread side-panel tabs surface.`,variables:{}},{id:"bbGuideThreadLifecycle",body:`Thread lifecycle
|
|
1720
|
-
|
|
1721
|
-
Lifecycle commands require an explicit thread ID or --self.
|
|
1722
|
-
|
|
1723
|
-
Lifecycle:
|
|
1724
|
-
|
|
1725
|
-
bb thread stop [id] Stop work and release the agent runtime
|
|
1726
|
-
bb thread compact [id] Request compaction of an idle or errored thread's context
|
|
1727
|
-
bb thread clear [id] Clear model context for an idle or failed thread
|
|
1728
|
-
bb thread cancel-plan [id] Exit the provider's active Plan mode
|
|
1729
|
-
bb thread clear-goal [id] Clear the provider's active Goal
|
|
1730
|
-
--self Target current thread
|
|
1731
|
-
|
|
1732
|
-
cancel-plan and clear-goal wait for the provider to confirm.
|
|
1733
|
-
\`thread compact\` enqueues the same structured /compact turn used by the
|
|
1734
|
-
composer. Follow the thread timeline for the eventual compaction result.
|
|
1735
|
-
\`thread clear\` keeps the BB thread, workspace, durable event history, and
|
|
1736
|
-
sticky execution settings. Its active timeline starts at one visible
|
|
1737
|
-
\`Context cleared\` boundary, and its next prompt starts a fresh provider
|
|
1738
|
-
conversation in the same thread. With
|
|
1739
|
-
\`bb settings general keepHistoryAfterContextClear true\`, earlier messages
|
|
1740
|
-
stay visible above that boundary. It is also the recovery for a send refused
|
|
1741
|
-
with \`provider_session_unavailable\` (\`details.reason\` foreign, ambiguous, or
|
|
1742
|
-
invalid: the recorded provider session belongs to another thread or has no
|
|
1743
|
-
usable identity).
|
|
1744
|
-
|
|
1745
|
-
bb thread retry [id] Retry the thread's failed turn
|
|
1746
|
-
--self Target current thread
|
|
1747
|
-
--turn <requestId> Retry this turn request id specifically; fails when it is not the thread's failed turn
|
|
1748
|
-
--send-at <when> Dispatch at an ISO 8601 timestamp or a duration from now (30s, 10m, 2h, 7d)
|
|
1749
|
-
--reason <text> Why it is being retried, shown on the queued row
|
|
1750
|
-
|
|
1751
|
-
Retry re-submits the failed turn by reference: no duplicated user message in
|
|
1752
|
-
the timeline, and an attempt number that increments (2 is the first retry).
|
|
1753
|
-
What the provider is sent follows its own acceptance record \u2014 an input it
|
|
1754
|
-
never accepted is re-sent verbatim, while an accepted turn (already in the
|
|
1755
|
-
provider's conversation) is continued with a nudge rather than asked twice.
|
|
1756
|
-
With no --turn it retries the most recent turn, the
|
|
1757
|
-
one whose failure put the thread in error; --turn asserts which turn you mean
|
|
1758
|
-
and fails when the thread has moved on, as does retrying a thread that has not
|
|
1759
|
-
failed (\`no_failed_turn\`) or a turn that already has a retry queued
|
|
1760
|
-
(\`retry_already_queued\`). Without --send-at the retry
|
|
1761
|
-
is attempted now, and may still queue behind a busy thread or a plugin.
|
|
1762
|
-
SDK: \`threads.retry({ threadId, turnRequestId?, sendAt?, reason? })\`.
|
|
1763
|
-
|
|
1764
|
-
bb thread archive [id] Archive a thread (and children/hidden forks)
|
|
1765
|
-
--self Archive current thread
|
|
1766
|
-
|
|
1767
|
-
Archive is not a hard stop: for 30 seconds a running turn and the thread's
|
|
1768
|
-
terminals keep going, and unarchiving within that window leaves everything in
|
|
1769
|
-
place. Use \`thread stop\` to end a run now.
|
|
1770
|
-
|
|
1771
|
-
\`thread stop\` preserves the thread history, metadata, environment, and future
|
|
1772
|
-
resume behavior. It stops active work and releases an idle agent runtime (bb
|
|
1773
|
-
also releases a runtime on its own after 30 idle minutes).
|
|
1774
|
-
The command succeeds when no runtime is loaded. Archive a finished hidden
|
|
1775
|
-
worker first, then stop it to release memory promptly. A stop that only
|
|
1776
|
-
releases an idle runtime adds no interruption: it leaves the timeline and any
|
|
1777
|
-
pending interaction of that thread untouched. An explicit stop wins over work
|
|
1778
|
-
that is still running: when the machine still runs a turn for a thread the app
|
|
1779
|
-
shows as idle or failed, or a turn starts while the stop is being delivered,
|
|
1780
|
-
the stop interrupts that turn and waits for the attempt. If the interrupt
|
|
1781
|
-
fails, the thread remains stopping; check \`bb thread show <id> --json\` before
|
|
1782
|
-
treating the stop as confirmed.
|
|
1783
|
-
|
|
1784
|
-
bb thread unarchive [id] Unarchive a thread
|
|
1785
|
-
--self Unarchive current thread
|
|
1786
|
-
|
|
1787
|
-
bb thread restore-environment [id] Restore a destroyed workspace
|
|
1788
|
-
--self Restore current thread
|
|
1789
|
-
|
|
1790
|
-
Archiving a thread retires its environment, and a managed workspace is removed
|
|
1791
|
-
from disk once the provider's grace window passes. Sending to a thread whose
|
|
1792
|
-
workspace is gone fails; \`restore-environment\` asks the environment provider
|
|
1793
|
-
to build it again and attaches it, leaving the conversation where it was.
|
|
1794
|
-
Each provider decides what that means: a worktree is re-created on the branch
|
|
1795
|
-
it held, a project checkout switches back to that branch, and a personal
|
|
1796
|
-
workspace cannot be restored. It starts no turn \u2014 the thread settles back to
|
|
1797
|
-
idle with a live workspace (check \`canRestoreEnvironment\` on \`bb thread show
|
|
1798
|
-
--json\`). Unarchive the thread first; the command is refused while the thread
|
|
1799
|
-
is archived, while its workspace is still there, and when the provider does
|
|
1800
|
-
not restore, is gone, or its machine is gone. Uncommitted changes in the
|
|
1801
|
-
removed workspace are not recoverable.
|
|
1802
|
-
|
|
1803
|
-
bb thread delete <id> Delete permanently
|
|
1804
|
-
--yes Skip confirmation
|
|
1805
|
-
|
|
1806
|
-
Deleting a thread permanently deletes its sidebar children and lifecycle
|
|
1807
|
-
dependents recursively, including hidden and archived descendants. This also
|
|
1808
|
-
applies to SDK \`threads.delete\`; set \`childThreadsConfirmed: true\` to confirm
|
|
1809
|
-
child deletion. Provider-owned environment cleanup is asynchronous. Use
|
|
1810
|
-
\`bb environment show <id>\` to inspect teardown until the lifecycle reaches
|
|
1811
|
-
destroyed. Deleting thread
|
|
1812
|
-
storage first stops processes whose working directory is inside it,
|
|
1813
|
-
including dev servers in nested checkouts (macOS and Linux only).`,variables:{}},{id:"bbGuideThreadMessaging",body:`Thread messaging
|
|
1814
|
-
|
|
1815
|
-
Messaging commands require an explicit thread ID or --self.
|
|
1816
|
-
|
|
1817
|
-
Messaging:
|
|
1818
|
-
|
|
1819
|
-
bb thread tell <id> <message> Send a follow-up message
|
|
1820
|
-
bb thread tell <id> --message-file <path>
|
|
1821
|
-
Read the message from a file; \`-\` reads stdin. Use this for
|
|
1822
|
-
multi-line or Markdown messages: inside double quotes the
|
|
1823
|
-
shell runs \`backticks\` and $(...) before bb sees them
|
|
1824
|
-
--mode <mode> Message mode: steer (default), queue, or auto
|
|
1825
|
-
--model <model> Model override for this turn
|
|
1826
|
-
--reasoning-level <level> Reasoning level override
|
|
1827
|
-
--plan Send the message as the provider's /plan action
|
|
1828
|
-
--send-at <when> Dispatch at an ISO 8601 timestamp or a duration from now (30s, 10m, 2h, 7d)
|
|
1829
|
-
--compact-first Compact the idle thread's context, then send when compaction finishes
|
|
1830
|
-
--file <path> CLI-local absolute path, file: URL, or uploaded file path
|
|
1831
|
-
--image <path> CLI-local absolute path, file: URL, or uploaded image path
|
|
1832
|
-
|
|
1833
|
-
Tell steers by default, delivering the message immediately into the active
|
|
1834
|
-
turn. Use --mode queue for non-urgent follow-ups that can wait until the agent
|
|
1835
|
-
is free; --mode auto steers a live turn and starts a new one on an idle
|
|
1836
|
-
thread. Input sent while a turn is starting stays in the queue with
|
|
1837
|
-
\`waitingOn: turn-starting\`; \`turn/started\` wakes it and steers it into that
|
|
1838
|
-
turn. A target that is awaiting user interaction (an open question or
|
|
1839
|
-
approval) cannot take a prompt; tell then adds the message to the thread's
|
|
1840
|
-
queue and dispatches it once the interaction settles. That outcome is not a
|
|
1841
|
-
failure, so do not resend. \`--json\` reports \`delivery\` as \`sent\` or \`queued\`,
|
|
1842
|
-
and a queued answer carries the complete row as \`queuedMessage\`, including
|
|
1843
|
-
its \`id\`, \`waitingOn\`, and \`sendAt\`. A deferred message waits for a thread
|
|
1844
|
-
that failed while it was deferred, and delivers when the thread is retried.
|
|
1845
|
-
|
|
1846
|
-
--plan sends the same structured /plan command the composer's plan action
|
|
1847
|
-
sends, so the agent proposes a plan for approval before executing (Claude
|
|
1848
|
-
Code and Codex threads). Plain "/plan ..." text is not recognized; it reaches
|
|
1849
|
-
the provider as literal text. Approve or deny the proposed plan with
|
|
1850
|
-
\`bb thread interactions\`; \`bb thread cancel-plan\` leaves Plan mode early.
|
|
1851
|
-
SDK callers build the same input with
|
|
1852
|
-
\`createBuiltinPlanCommandTextInput(text)\` from \`@bb/sdk\` and pass it as
|
|
1853
|
-
\`input\` to \`threads.spawn\` or \`threads.send\`.
|
|
1854
|
-
|
|
1855
|
-
Ownership:
|
|
1856
|
-
|
|
1857
|
-
bb thread update [id] Update thread metadata
|
|
1858
|
-
--self Target current thread
|
|
1859
|
-
--title <title> Set title
|
|
1860
|
-
--parent-thread <id> Assign to a parent thread
|
|
1861
|
-
--clear-parent-thread Remove parent assignment
|
|
1862
|
-
--section <id> Move into a section
|
|
1863
|
-
--clear-section Remove section assignment
|
|
1864
|
-
--model <model> Set the sticky model for the next and later turns
|
|
1865
|
-
--reasoning-level <level> Set the sticky reasoning level (provider-dependent)
|
|
1866
|
-
--visibility <visibility> Set visible or hidden
|
|
1867
|
-
--parent-notifications <value> Set auto, stuck, or off (applies to later outcomes)
|
|
1868
|
-
|
|
1869
|
-
Clearing a parent inherits the former parent's section unless --section or
|
|
1870
|
-
--clear-section is also supplied. Children released by environment archiving
|
|
1871
|
-
also inherit their former parent's section.
|
|
1872
|
-
|
|
1873
|
-
Model and reasoning updates stay within the thread's current provider. BB
|
|
1874
|
-
validates them against that provider's current model catalog, applies them on
|
|
1875
|
-
the next turn, and keeps using them on later turns until changed.
|
|
1876
|
-
|
|
1877
|
-
bb thread read [id] Mark read
|
|
1878
|
-
bb thread unread [id] Mark unread
|
|
1879
|
-
bb thread reorder-pinned <id> [--after <id>] [--before <id>]
|
|
1880
|
-
|
|
1881
|
-
Interactions:
|
|
1882
|
-
|
|
1883
|
-
bb thread interactions list [id] List a thread's pending and past interactions
|
|
1884
|
-
bb thread interactions show <interaction-id> [id]
|
|
1885
|
-
Show one interaction (approval details, questions, or a plugin form's data)
|
|
1886
|
-
bb thread interactions approve <interaction-id> [id]
|
|
1887
|
-
Allow a command, file-change, plan, or tool-use approval
|
|
1888
|
-
bb thread interactions deny <interaction-id> [id]
|
|
1889
|
-
Deny an approval
|
|
1890
|
-
bb thread interactions grant <interaction-id> [id] --scope turn|session
|
|
1891
|
-
Grant a permission interaction
|
|
1892
|
-
bb thread interactions answer <interaction-id> [id] --choice <questionId=value> --text <questionId=text>
|
|
1893
|
-
Answer a provider's user question
|
|
1894
|
-
bb thread interactions respond <interaction-id> [id] --value '<json>'
|
|
1895
|
-
Answer a plugin form: a plugin's own request, or a request the agent raised through a provider (kind \`<pluginId>/<name>\`)
|
|
1896
|
-
--self Target current thread (every subcommand)
|
|
1897
|
-
--json Machine-readable output (every subcommand)
|
|
1898
|
-
|
|
1899
|
-
\`show\` prints a plugin form's \`Data\` so you can shape the \`--value\` JSON.
|
|
1900
|
-
A provider's plugin-defined request cannot be cancelled; stop the thread to
|
|
1901
|
-
back out of it.
|
|
1902
|
-
|
|
1903
|
-
Queued messages:
|
|
1904
|
-
|
|
1905
|
-
bb thread queue list [<thread-id>] [--wait-holder plugin:<plugin-id>]
|
|
1906
|
-
bb thread queue create <thread-id> <message> [--file <path>] [--image <path>]
|
|
1907
|
-
bb thread queue update <thread-id> <message-id> <message> [--file <path>] [--image <path>]
|
|
1908
|
-
create and update also take --message-file <path>
|
|
1909
|
-
bb thread queue send <thread-id> <message-id> [--mode auto|steer]
|
|
1910
|
-
bb thread queue reorder <thread-id> <message-id> [--after <id>] [--before <id>]
|
|
1911
|
-
bb thread queue group <thread-id> <boundary-id> --prefix <comma-separated-ids>
|
|
1912
|
-
bb thread queue delete <thread-id> <message-id>
|
|
1913
|
-
|
|
1914
|
-
The \`Sender\` column identifies agent threads and system notices; user messages
|
|
1915
|
-
leave it blank. The SDK and \`--json\` include \`initiator\` and \`senderThreadId\`.
|
|
1916
|
-
SDK: \`threads.queue.list\` (all threads) and
|
|
1917
|
-
\`threads.queuedMessages.list|send|update|delete\` (one thread).
|
|
1918
|
-
|
|
1919
|
-
A queued message is one that could not dispatch yet. It is not in the
|
|
1920
|
-
timeline or \`thread log\` until it dispatches; thread list rows carry
|
|
1921
|
-
\`queuedWork: none|waiting|failed\`. Every one carries a typed reason in its
|
|
1922
|
-
\`Waiting on\` column (\`waitingOn.kind\` in JSON: \`thread-busy\`,
|
|
1923
|
-
\`turn-starting\`, \`provisioning\`, \`host-offline\`, \`interaction\`, \`time\` for
|
|
1924
|
-
\`Send at\`, or \`plugin\` with \`pluginId\` and a reason). \`queue list\` with no thread id lists every
|
|
1925
|
-
queued row in the workspace; \`--wait-holder plugin:<plugin-id>\` narrows it to
|
|
1926
|
-
the rows one plugin is holding.
|
|
1927
|
-
|
|
1928
|
-
The \`State\` column (\`state\` in the SDK and \`--json\`) is one of \`queued\` (next
|
|
1929
|
-
behind the running turn), \`scheduled\` (goes at \`Send at\`), \`waiting\` (held by
|
|
1930
|
-
its typed reason), \`failed_retrying\` (an automatic retry is booked),
|
|
1931
|
-
\`failed_exhausted\` (retries spent; waits for you), or \`claimed\` (a dispatch
|
|
1932
|
-
attempt is sending it).
|
|
1933
|
-
|
|
1934
|
-
Failed rows show their failure reason instead of their previous wait, followed
|
|
1935
|
-
by a recovery command: \`bb thread queue send <thread-id> <message-id>\`.
|
|
1936
|
-
Use it to retry immediately, including after automatic retries are exhausted.
|
|
1937
|
-
Editing the message does not clear its failure or trigger a retry.
|
|
1938
|
-
|
|
1939
|
-
\`queue send\` dispatches a row now, bypassing every plugin wait and its own
|
|
1940
|
-
schedule \u2014 the invariants (a running turn, an unfinished workspace, an
|
|
1941
|
-
unanswered interaction) still apply, and a message that hits one simply queues
|
|
1942
|
-
again. \`--mode steer\` uses those same send-now bypasses and re-attempts the row
|
|
1943
|
-
as a steer; it does not bypass the invariants, so a provisioning row remains
|
|
1944
|
-
queued until the workspace is ready.
|
|
1945
|
-
\`queue delete\` discards it instead. Both are always permitted.
|
|
1946
|
-
|
|
1947
|
-
--compact-first runs the same /compact turn as \`bb thread compact\` and queues
|
|
1948
|
-
the message behind it, so it needs an idle or errored thread whose provider
|
|
1949
|
-
supports manual compaction; it cannot be combined with --send-at. The SDK
|
|
1950
|
-
takes \`compactFirst: true\` on \`threads.send\`, which also rejects
|
|
1951
|
-
\`mode: "steer"\`.
|
|
1952
|
-
|
|
1953
|
-
--send-at takes an ISO 8601 timestamp (2026-08-25T09:00, local without an
|
|
1954
|
-
offset) or a duration from now (30s, 10m, 2h, 7d). A time that has already
|
|
1955
|
-
passed is rejected, as is a bare date, which has no time of day. Several
|
|
1956
|
-
queued rows on one thread are normal: two scheduled sends coexist. A
|
|
1957
|
-
scheduled spawn creates a \`pending\` thread and does no environment work (no
|
|
1958
|
-
worktree, no setup script) until it is due. The SDK takes \`sendAt\` in epoch
|
|
1959
|
-
milliseconds on \`threads.spawn\` and \`threads.send\`.`,variables:{}},{id:"bbGuideThreads",body:`Thread commands
|
|
1960
|
-
|
|
1961
|
-
Every command supports --json for machine-readable output. Read-only commands
|
|
1962
|
-
take a thread ID or --self where supported; mutating lifecycle and messaging
|
|
1963
|
-
commands require an explicit ID or --self.
|
|
1964
|
-
|
|
1965
|
-
Thread commands are split across four chapters:
|
|
1966
|
-
|
|
1967
|
-
threads Spawning, handing off, forking, and editing sent messages
|
|
1968
|
-
thread-inspection Listing, sections, inspecting, waiting, opening in the app,
|
|
1969
|
-
and panel tabs
|
|
1970
|
-
thread-messaging Messages, plan mode, metadata and ownership, interactions,
|
|
1971
|
-
and queued messages
|
|
1972
|
-
thread-lifecycle Stop, compact, clear, retry, archive, and delete
|
|
1973
|
-
|
|
1974
|
-
Spawning:
|
|
1975
|
-
|
|
1976
|
-
bb thread spawn --project <id> --prompt "..." [options]
|
|
1977
|
-
bb thread spawn --project <id> --prompt-file <path> [options]
|
|
1978
|
-
|
|
1979
|
-
--prompt <prompt> Initial prompt (one of --prompt or --prompt-file is required)
|
|
1980
|
-
--prompt-file <path> Read the prompt from a file; \`-\` reads stdin. Use this for
|
|
1981
|
-
multi-line or Markdown prompts: inside double quotes the shell
|
|
1982
|
-
runs \`backticks\` and $(...) before bb sees them
|
|
1983
|
-
--title <title> Thread title
|
|
1984
|
-
--project <id> Project (required; when omitted the error prints this thread's project ID to add)
|
|
1985
|
-
--parent-thread <id> Parent thread (may be in another project)
|
|
1986
|
-
--parent-self Parent to the current thread (BB_THREAD_ID)
|
|
1987
|
-
--lifecycle-owner-thread <id> Archive/delete with this owner
|
|
1988
|
-
--provider <id> Provider override
|
|
1989
|
-
--model <model> Model override
|
|
1990
|
-
--reasoning-level <level> Reasoning level id the model lists: low, medium, high, xhigh, max, or a provider-specific id
|
|
1991
|
-
--environment <id-or-path> Attach to an existing environment (ID or workspace path)
|
|
1992
|
-
--new-environment <kind> Create a fresh personal workspace or managed worktree
|
|
1993
|
-
--base-branch <branch> Exact Git ref for a new managed worktree
|
|
1994
|
-
(--new-environment worktree only; an
|
|
1995
|
-
--environment-provider takes its branch
|
|
1996
|
-
through --environment-inputs)
|
|
1997
|
-
--environment-provider <id> Run on an environment provider by id (list them with
|
|
1998
|
-
\`bb environment providers\`). The provider
|
|
1999
|
-
provisions where the thread runs; its steps show in the
|
|
2000
|
-
thread's workspace-setup block. Its \`requires\` names the
|
|
2001
|
-
facts it consumes: \`host\` takes --machine (the local
|
|
2002
|
-
machine by default); \`gitCheckout\` needs this project's
|
|
2003
|
-
checkout on that machine to be a Git repository with
|
|
2004
|
-
commits; \`gitRemote\` needs a project remote;
|
|
2005
|
-
\`projectless\` serves only threads with no project.
|
|
2006
|
-
--environment-inputs <json> JSON value for an --environment-provider that declares
|
|
2007
|
-
inputs; \`bb environment providers --json\` prints each
|
|
2008
|
-
provider's inputs as JSON Schema (null when it takes
|
|
2009
|
-
none). Omitted, it defaults to {} when the schema
|
|
2010
|
-
accepts an empty object and is otherwise required;
|
|
2011
|
-
refused when the provider declares no inputs
|
|
2012
|
-
--machine <id-or-name> Run on a machine (--host is an alias)
|
|
2013
|
-
--service-tier <tier> Service tier id the provider lists for the model, such as
|
|
2014
|
-
default or fast (see \`bb provider models\`)
|
|
2015
|
-
--option <option=value> Choose a value for an option the provider's model lists, applied
|
|
2016
|
-
before the first message; true or false for an on/off option
|
|
2017
|
-
(repeatable; see \`bb provider models\`)
|
|
2018
|
-
--permission-mode <mode> Permission mode: accept-edits, auto, or full
|
|
2019
|
-
--plan Send the prompt as the provider's /plan action (plan first, execute after approval)
|
|
2020
|
-
--section <id> Create the thread in a section
|
|
2021
|
-
--pinned Create the thread in Pinned (combines with --section;
|
|
2022
|
-
unpinning reveals it in that section)
|
|
2023
|
-
--visibility <visibility> visible or hidden; a child inherits its parent by default
|
|
2024
|
-
--parent-notifications <value> auto (default), stuck, or off; which outcomes wake the parent
|
|
2025
|
-
--send-at <when> Dispatch the first message at an ISO 8601 timestamp or a duration from now (30s, 10m, 2h, 7d)
|
|
2026
|
-
--file <path> CLI-local absolute path, file: URL, or uploaded file path
|
|
2027
|
-
--image <path> CLI-local absolute path, file: URL, or uploaded image path
|
|
2028
|
-
--origin-kind <kind> Create a fork thread
|
|
2029
|
-
--source-thread <id> Source thread for a fork
|
|
2030
|
-
--source-seq-end <seq> Fork after the source turn containing this event sequence
|
|
2031
|
-
|
|
2032
|
-
Execution defaults resolve from explicit flags, live parent execution, and
|
|
2033
|
-
remembered project defaults. With no remembered model, bb uses the explicitly
|
|
2034
|
-
requested provider or Codex and resolves its provider-reported default model
|
|
2035
|
-
on the target machine (or the first catalog model when none is marked). The product reasoning and permission defaults are
|
|
2036
|
-
medium and auto.
|
|
2037
|
-
accept-edits uses workspace sandboxing with user-reviewed escalation. auto uses
|
|
2038
|
-
the same workspace sandbox with provider-native automatic review. full is the
|
|
2039
|
-
explicit sandbox and approval bypass. Plan mode is separate from permissions.
|
|
2040
|
-
Subagents inherit the parent's permission mode by default, adapted to the child provider's supported modes. Explicit requests and a thread's recorded mode take precedence; nesting a thread does not cap its permissions. The host permission ceiling still applies.
|
|
2041
|
-
Parenting is opt-in. Inside a thread, pass --parent-self to parent the new thread to the current thread.
|
|
2042
|
-
Hidden threads are for plugin/background workers. They remain addressable by
|
|
2043
|
-
ID while staying out of sidebar organization and unread/pending favicon
|
|
2044
|
-
attention. Thread lists exclude them unless
|
|
2045
|
-
--include-hidden is passed; direct-ID operations remain available.
|
|
2046
|
-
A new child thread inherits the visibility of its parent, so the subagents of
|
|
2047
|
-
a hidden thread stay hidden too. Pass --visibility to override the inherited
|
|
2048
|
-
value. A hidden child still reports its turns and blockers to its parent
|
|
2049
|
-
thread; only source-derived forks stay silent.
|
|
2050
|
-
--parent-notifications chooses which child outcomes wake the parent. auto
|
|
2051
|
-
reports every finished, failed, or interrupted turn and every blocker. stuck
|
|
2052
|
-
skips completed turns and keeps failures, interruptions, and blockers on an
|
|
2053
|
-
approval or question; the child sends its results with \`bb thread tell\`, so
|
|
2054
|
-
say so in its prompt. off reports nothing. Under stuck and off, unassigning
|
|
2055
|
-
the child does not notify the former parent either. \`bb status\` and
|
|
2056
|
-
\`bb thread show\` print the value for a child thread.
|
|
2057
|
-
A machine selector accepts an exact ID or an unambiguous name. It works with
|
|
2058
|
-
an unmanaged --environment path, --new-environment worktree, or the personal
|
|
2059
|
-
workspace. It cannot be combined with an existing environment ID because that
|
|
2060
|
-
environment already selects its machine. Without the flag, local/server
|
|
2061
|
-
machine resolution is unchanged.
|
|
2062
|
-
Omit --base-branch for bb's default. Explicit values are exact; use
|
|
2063
|
-
origin/<branch> for a remote ref.
|
|
2064
|
-
With no environment flag, a new thread gets a fresh worktree of the
|
|
2065
|
-
project's default branch (the project checkout when the project has no
|
|
2066
|
-
branch) on the primary host, or on the persistent machine that holds the
|
|
2067
|
-
project's source when the primary host has none. A child of a live thread
|
|
2068
|
-
in the same project gets a worktree on its parent's machine.
|
|
2069
|
-
Before selecting a provider, run \`bb environment providers --project <id>
|
|
2070
|
-
--machine <id-or-name>\` to see whether it is available, needs setup, or is
|
|
2071
|
-
unavailable and why. The first-party providers are Project checkout,
|
|
2072
|
-
Worktree, and Personal workspace.
|
|
2073
|
-
|
|
2074
|
-
Handoff:
|
|
2075
|
-
The app's Handoff to new thread (in the follow-up model picker) starts a new
|
|
2076
|
-
thread that references the source. From the CLI, run bb thread spawn with
|
|
2077
|
-
--provider, --model, --environment and --prompt 'Continue from
|
|
2078
|
-
@thread:THREAD_ID ...'; SDK callers pass the same fields to threads.spawn.
|
|
2079
|
-
|
|
2080
|
-
Forking:
|
|
2081
|
-
|
|
2082
|
-
bb thread fork <source-thread-id> [options]
|
|
2083
|
-
|
|
2084
|
-
--prompt <prompt> Optional first prompt; omit for an idle fork
|
|
2085
|
-
--prompt-file <path> Read the first prompt from a file; \`-\` reads stdin
|
|
2086
|
-
--lifecycle-owner-thread <id> Archive/delete with this owner
|
|
2087
|
-
--source-seq-end <seq> Fork after the source turn containing this event sequence (tip by default)
|
|
2088
|
-
--environment <id-or-path> Existing environment ID or unmanaged workspace path
|
|
2089
|
-
--new-environment <kind> Create a fresh personal workspace or managed worktree
|
|
2090
|
-
--base-branch <branch> Exact Git ref for a new worktree; omit for the project default
|
|
2091
|
-
--title <title> Thread title (idle forks default to "(1) <source title>")
|
|
2092
|
-
--permission-mode <mode> Inherit source by default; accepts accept-edits, auto, full
|
|
2093
|
-
--visibility <visibility> visible (default) or hidden
|
|
2094
|
-
--agent-context-seed <text> Persist agent-only context without a first run
|
|
2095
|
-
--file <path> CLI-local absolute path, file: URL, or uploaded file path
|
|
2096
|
-
--image <path> CLI-local absolute path, file: URL, or uploaded image path
|
|
2097
|
-
|
|
2098
|
-
Forks clone the source provider session on the same machine and inherit the
|
|
2099
|
-
source conversation in their timeline. --source-seq-end anchors the fork on
|
|
2100
|
-
the completed source turn that contains that sequence: the clone and the
|
|
2101
|
-
inherited timeline both end with that turn (an anchor on a user message
|
|
2102
|
-
branches before it, like editing it). Without it a fork clones the session
|
|
2103
|
-
tip and inherits every completed turn. Providers that can only clone a whole
|
|
2104
|
-
session accept an anchor only on the source's latest turn. A fork reuses the
|
|
2105
|
-
source environment by default. Use --new-environment personal for a fresh
|
|
2106
|
-
personal workspace or --new-environment worktree for a fresh worktree on the
|
|
2107
|
-
source machine; --environment can select another environment or unmanaged
|
|
2108
|
-
path on that machine. A different machine is rejected because the source
|
|
2109
|
-
provider session lives on its original machine. Omit --prompt to create an
|
|
2110
|
-
idle fork. A visible idle fork without --title is named after its source with
|
|
2111
|
-
a numbered prefix: "foo" becomes "(1) foo" and "(1) foo" becomes "(2) foo".
|
|
2112
|
-
Forks created with a first prompt get a title from that prompt.
|
|
2113
|
-
|
|
2114
|
-
Editing a sent message:
|
|
2115
|
-
|
|
2116
|
-
bb thread edit-message <id> --message "Replacement text"
|
|
2117
|
-
--message-file <path> Read the replacement from a file; \`-\` reads stdin
|
|
2118
|
-
--self Target the current thread (BB_THREAD_ID)
|
|
2119
|
-
--expected-request-sequence <seq> Select the message and reject a stale target
|
|
2120
|
-
|
|
2121
|
-
Without --expected-request-sequence, the latest eligible message is edited.
|
|
2122
|
-
Codex, Claude Code, and Pi threads are supported, including failed and
|
|
2123
|
-
incomplete turns; grouped multi-message requests are not editable.
|
|
2124
|
-
\`canEditMessages\` on \`bb thread show --json\` reports whether the thread's
|
|
2125
|
-
provider and archive state allow edits. The
|
|
2126
|
-
original conversation remains unchanged until the provider prepares the
|
|
2127
|
-
replacement history. If the thread is running,
|
|
2128
|
-
submission stops the current turn and waits for it to settle. Provider-owned
|
|
2129
|
-
background commands, agents, and workflows are stopped before replacing the
|
|
2130
|
-
session, and retained task cards keep their terminal status. Durable runs
|
|
2131
|
-
managed by the Workflows plugin continue independently. It then
|
|
2132
|
-
replaces the selected turn and every later turn while retaining workspace
|
|
2133
|
-
changes. Unsent queued messages remain in the queue and dispatch after the
|
|
2134
|
-
replacement turn when their waits clear. An already-sending queued message
|
|
2135
|
-
must finish before the edit can start. Retries of turns replaced by the edit
|
|
2136
|
-
are removed from the queue. From an agent thread, the command
|
|
2137
|
-
carries \`BB_THREAD_ID\` so the replacement runs under agent permission policy.
|
|
2138
|
-
An edit is refused if removing its history would erase ownership evidence
|
|
2139
|
-
shared with another thread. Use bb thread clear <id> to start a new session
|
|
2140
|
-
while keeping the history and its ownership evidence.
|
|
2141
|
-
|
|
2142
|
-
Lifecycle ownership:
|
|
2143
|
-
spawn and fork accept --lifecycle-owner-thread <id> (SDK
|
|
2144
|
-
lifecycleOwnerThreadId, also returned in thread responses, null if
|
|
2145
|
-
independent). The owner must be live; projects, hosts and environments may
|
|
2146
|
-
differ. Ownership is immutable. Archiving the owner archives and stops its
|
|
2147
|
-
dependents; deleting it deletes them. Unarchive the owner before explicitly
|
|
2148
|
-
restoring a dependent. Stop does not cascade. Sidebar parents and ordinary
|
|
2149
|
-
forks keep their own policies.`,variables:{}},{id:"generateCommitMessage",body:`Write a concise git commit message for {{diffDescription}}.
|
|
2150
|
-
Reply with only the commit message line, without quotes or explanation.
|
|
2151
|
-
Rules:
|
|
2152
|
-
- Use conventional commit style (feat|fix|refactor|test|docs|chore|perf|build|ci|style).
|
|
2153
|
-
- Prefer specific types like feat/fix/refactor/test/docs/perf over chore.
|
|
2154
|
-
- Use chore only for housekeeping (deps, tooling, CI, formatting, repo maintenance).
|
|
2155
|
-
- Use imperative mood, max 72 characters.
|
|
2156
|
-
- Single line only, no body.
|
|
2157
|
-
|
|
2158
|
-
Shortstat:
|
|
2159
|
-
{{shortstat}}
|
|
2160
|
-
|
|
2161
|
-
Files (name-status):
|
|
2162
|
-
{{files}}
|
|
2163
|
-
|
|
2164
|
-
Patch excerpt:
|
|
2165
|
-
{{patch}}`,variables:{diffDescription:"Human-readable description of the diff snapshot being summarized.",shortstat:"Git shortstat summary for the diff.",files:"Git name-status output for changed files.",patch:"Trimmed patch excerpt for extra context."}},{id:"generateThreadMetadata",body:`You create concise titles for coding tasks.
|
|
2166
|
-
Reply with only the title: short, clear, sentence case, in the same language as the task. Keep it under about 40 characters; for scripts that do not separate words with spaces, that is roughly 20 characters. Summarize the task in your own words instead of copying its text. No quotes, no trailing punctuation, no explanation.
|
|
2167
|
-
|
|
2168
|
-
Consider the user's intent when titling to make it useful. For instance, if they detail specific tools to use to solve a problem, it is the problem that should be the title, not the tools that should be used.
|
|
2169
|
-
|
|
2170
|
-
{{#if invokedCommands}}
|
|
2171
|
-
The prompt invokes these commands or skills: {{invokedCommands}}. They name how the work is carried out, so title the work they are applied to. When the prompt names nothing else, title what the invoked command itself does.
|
|
2172
|
-
|
|
2173
|
-
{{/if}}
|
|
2174
|
-
Task:
|
|
2175
|
-
{{cleanedPrompt}}`,variables:{cleanedPrompt:"User task text with normalized whitespace, clamped to 4000 columns.",invokedCommands:"Comma-separated slash commands or skills the prompt invokes, when it invokes any."}},{id:"systemMessageChildThreadNeedsAttention",body:`[bb system]
|
|
2176
|
-
|
|
2177
|
-
{{threadMention}} needs help.
|
|
2178
|
-
{{blockerSummary}}
|
|
2179
|
-
|
|
2180
|
-
Review the blocker. If you can resolve it from existing context, reply to the thread with guidance. Otherwise, ask the user for the missing decision.`,variables:{blockerSummary:"Compact summary of the pending interaction, or a fallback sentence when no safe summary is available.",threadMention:"Serialized thread mention token, e.g. '@thread:thr_abc123'."}},{id:"systemMessageChildThreadOutcomeBatch",body:`[bb system]
|
|
2181
|
-
|
|
2182
|
-
{{updates}}`,variables:{updates:"Rendered child thread outcome message body."}},{id:"systemMessageEnvironmentDirectoryUpdated",body:"[bb system]\n\nThis thread now runs in `{{path}}`. Continue the task from your previous turn in this directory.",variables:{path:"Absolute path of the thread's new working directory."}},{id:"systemMessageThreadOwnershipAssigned",body:`[bb system]
|
|
2183
|
-
|
|
2184
|
-
{{threadMention}} is now a child of this thread.`,variables:{threadMention:"Serialized thread mention token, e.g. '@thread:thr_abc123'."}},{id:"systemMessageThreadOwnershipRemoved",body:`[bb system]
|
|
2185
|
-
|
|
2186
|
-
{{threadMention}} is no longer a child of this thread.`,variables:{threadMention:"Serialized thread mention token, e.g. '@thread:thr_abc123'."}}];var Gs={threads:"bbGuideThreads","thread-inspection":"bbGuideThreadInspection","thread-messaging":"bbGuideThreadMessaging","thread-lifecycle":"bbGuideThreadLifecycle",environments:"bbGuideEnvironments","agent-configuration":"bbGuideAgentConfiguration",providers:"bbGuideProviders",projects:"bbGuideProjects",machines:"bbGuideMachines",terminals:"bbGuideTerminals",browser:"bbGuideBrowser",customization:"bbGuideCustomization",plugins:"bbGuidePlugins",json:"bbGuideJson"},hc={thread:"threads",spawn:"threads",fork:"threads",permission:"threads",permissions:"threads",inspection:"thread-inspection",inspect:"thread-inspection",wait:"thread-inspection",section:"thread-inspection",sections:"thread-inspection",messaging:"thread-messaging",message:"thread-messaging",messages:"thread-messaging",tell:"thread-messaging",interaction:"thread-messaging",interactions:"thread-messaging",queue:"thread-messaging",lifecycle:"thread-lifecycle",retry:"thread-lifecycle",archive:"thread-lifecycle",environment:"environments",env:"environments",worktree:"environments",worktrees:"environments",agent:"agent-configuration",agents:"agent-configuration",skill:"agent-configuration",skills:"agent-configuration",provider:"providers",model:"providers",models:"providers",project:"projects",machine:"machines",host:"machines",hosts:"machines",server:"machines",terminal:"terminals",theme:"customization",settings:"customization",plugin:"plugins",marketplace:"plugins",automation:"plugins",automations:"plugins","json-output":"json",output:"json",errors:"json"};function gc(n){let t=n.trim().toLowerCase();return hc[t]??t}var fc=new Map(Qs.map(n=>[n.id,n.body]));function Js(n){let t=fc.get(n);if(t===void 0)throw new Error(`Template '${n}' is unavailable.`);return t}function Ln(){return{render(n={}){if(!n.chapter)return{content:Js("bbGuideOverview")};let t=gc(n.chapter),r=Gs[t];if(!r){let s=Object.keys(Gs).join(", ");throw new Error(`Unknown guide chapter '${n.chapter}'. Available: ${s}. Commands contributed by plugins document themselves: run \`bb <command> --help\`.`)}return{chapter:t,content:Js(r)}}}}var Ks=e.object({id:e.string(),text:e.string(),startedAt:e.number(),updatedAt:e.number()});var bc=["app","cli","sdk","plugin"],qe=e.enum(bc);var yc=["time","thread-busy","stopping","turn-starting","provisioning","host-offline","interaction","plugin"],eS=e.enum(yc),vc=e.string().min(1).max(200),Sc=200,Rt=e.string().min(1).max(Sc),Tt=e.discriminatedUnion("kind",[e.object({kind:e.literal("time")}),e.object({kind:e.literal("thread-busy")}),e.object({kind:e.literal("stopping")}),e.object({kind:e.literal("turn-starting")}),e.object({kind:e.literal("provisioning")}),e.object({kind:e.literal("host-offline"),hostName:vc}),e.object({kind:e.literal("interaction")}),e.object({kind:e.literal("plugin"),pluginId:k,reason:Rt})]),xc=200,Vs=e.string().min(1).max(xc),Rc="plugin:",Xs=e.templateLiteral([Rc,k]),Tc=["inline","retry"],tS=e.enum(Tc),Ys=e.discriminatedUnion("kind",[e.object({kind:e.literal("inline")}),e.object({kind:e.literal("retry"),retryOfTurnRequestId:pe,attempt:e.number().int().min(2),reason:Rt})]),nS=e.object({kind:mt,subject:ht.nullable()});var wc=["queued","scheduled","waiting","failed_retrying","failed_exhausted","claimed"],Zs=e.enum(wc);var wt=["pending","idle","starting","active","stopping","error"],B=e.enum(wt);var kc=["fork"],he=e.enum(kc);var Pc=["auto","stuck","off"],Ue=e.enum(Pc);var Ac=["visible","hidden"],ge=e.enum(Ac);var Ic=[...wt,"provisioning","waiting-for-host"],Ec=e.enum(Ic),Be=e.object({displayStatus:Ec}),ze=e.object({activeWorkflowCount:e.number().int().nonnegative(),activeBackgroundAgentCount:e.number().int().nonnegative(),activeBackgroundCommandCount:e.number().int().nonnegative(),activePlanModeCount:e.number().int().nonnegative(),activeGoalCount:e.number().int().nonnegative()});var Cc=["clean","untracked","dirty_uncommitted","committed_unmerged","dirty_and_committed_unmerged"],jc=e.enum(Cc),_c=e.enum(["M","A","D","R","C","U","??","?"]),Mc=e.object({path:e.string(),status:_c,insertions:e.number().nullable(),deletions:e.number().nullable()}),Dc=e.object({sha:e.string(),shortSha:e.string(),subject:e.string(),authorName:e.string(),authoredAt:e.number()}),ei=e.object({insertions:e.number(),deletions:e.number(),lineStatsComplete:e.boolean(),fileCount:e.number().int().nonnegative(),files:e.array(Mc)}),Oc=ei.extend({hasUncommittedChanges:e.boolean(),state:jc}),Lc=e.object({currentBranch:e.string().nullable(),defaultBranch:e.string()}),qc=ei.extend({mergeBaseBranch:e.string(),baseRef:e.string().nullable(),aheadCount:e.number(),behindCount:e.number(),squashMergeCheckComplete:e.boolean(),hasCommittedUnmergedChanges:e.boolean(),commits:e.array(Dc)}),ti=e.object({workingTree:Oc,checkout:Pn,branch:Lc,mergeBase:qc.nullable()}),qn=e.object({id:e.string(),origin:qe.nullable(),originPluginId:e.string().nullable(),initiator:e.enum(["user","agent","system"]),senderThreadId:e.string().nullable(),threadId:e.string(),content:e.array(_).min(1),model:e.string().min(1),reasoningLevel:O,permissionMode:L,serviceTier:K,groupWithNext:e.boolean(),sendAt:e.number().int().nonnegative().nullable(),state:Zs,waitingOn:Tt.nullable(),failureReason:Vs.nullable(),payload:Ys,editable:e.boolean(),createdAt:e.number(),updatedAt:e.number()}),Uc=e.object({id:e.string(),projectId:e.string(),environmentId:e.string().nullable(),providerId:e.string(),title:e.string().nullable(),titleFallback:e.string().nullable(),sectionId:e.string().nullable(),status:B,parentThreadId:e.string().nullable(),lifecycleOwnerThreadId:e.string().nullable(),sourceThreadId:e.string().nullable(),originKind:he.nullable(),originPluginId:e.string().nullable(),visibility:ge,parentNotifications:Ue,archivedAt:e.number().nullable(),pinnedAt:e.number().nullable(),deletedAt:e.number().nullable(),lastReadAt:e.number().nullable(),latestAttentionAt:e.number(),createdAt:e.number(),updatedAt:e.number()}),Un=Uc.extend({runtime:Be}),Bc=["none","waiting","failed"],zc=e.enum(Bc),Ne=Un.extend({activity:ze,queuedWork:zc,pinSortKey:e.string().nullable(),hasPendingInteraction:e.boolean(),environmentHostId:e.string().nullable(),environmentName:e.string().nullable(),environmentBranchName:e.string().nullable(),environmentPath:e.string().nullable(),environmentProviderId:e.string().nullable(),environmentIsWorktree:e.boolean().nullable(),environmentWorkspaceDisplayKind:zs});var ni=["thread-created","thread-deleted","events-appended","history-rewritten","history-compacted","interactions-changed","status-changed","title-changed","queue-changed","archived-changed","pin-state-changed","parent-changed","environment-changed","read-state-changed","tabs-changed","terminals-changed"],ri=["project-created","project-updated","project-deleted","project-sources-changed","threads-changed","project-order-changed"],si=["environment-created","environment-deleted","metadata-changed","status-changed","work-status-changed","git-refs-changed","thread-storage-changed","diff-viewed-changed"],ii=["host-connected","host-disconnected","provider-model-catalog-changed"],oi=["config-changed","plugins-changed","plugin-install-jobs-changed","plugin-update-jobs-changed","provider-registrations-changed","environment-availability-changed","server-move-changed","app-update-changed"],Nc=e.enum(ni),Hc=e.enum(ri),Fc=e.enum(si),Wc=e.enum(ii),$c=e.enum(oi),He=e.object({kind:e.literal("thread-timeline"),threadId:e.string().min(1),segmentLimit:e.number().int().positive().nullable(),deferContent:e.boolean()}).strict();function kt(n){return n===null||typeof n!="object"?JSON.stringify(n):Array.isArray(n)?`[${n.map(kt).join(",")}]`:`{${Object.keys(n).sort().map(t=>`${JSON.stringify(t)}:${kt(n[t])}`).join(",")}}`}var Qc=e.object({kind:e.literal("plugin-read"),pluginId:e.string().min(1),method:e.string().min(1),read:e.union([e.object({input:S}).strict(),e.object({key:e.string()}).strict()]).refine(n=>new TextEncoder().encode(kt(n)).byteLength<=16384,"Plugin read input exceeds 16 KiB")}).strict(),Bn=e.discriminatedUnion("kind",[Qc,e.object({kind:e.literal("plugin"),pluginId:e.string().min(1)}).strict(),e.object({kind:e.literal("thread-detail"),threadId:e.string().min(1)}).strict(),He,e.object({kind:e.literal("thread-list")}).strict(),e.object({kind:e.literal("project-detail"),projectId:e.string().min(1)}).strict(),e.object({kind:e.literal("project-list")}).strict(),e.object({kind:e.literal("environment-detail"),environmentId:e.string().min(1)}).strict(),e.object({kind:e.literal("environment-list")}).strict(),e.object({kind:e.literal("host-detail"),hostId:e.string().min(1)}).strict(),e.object({kind:e.literal("host-list")}).strict(),e.object({kind:e.literal("system")}).strict()]);function ai(n){return Bn.safeParse(n).success}var Gc=e.preprocess(n=>Array.isArray(n)?n.filter(ai):n,e.array(Bn)),Jc=e.preprocess(n=>n===void 0||ai(n)?n:null,Bn.nullable().optional()),li={target:Jc,targets:Gc.optional()},di=n=>n.target!==void 0!=(n.targets!==void 0),Kc=e.object({type:e.literal("subscribe"),...li}).refine(di),Vc=e.object({type:e.literal("unsubscribe"),...li}).refine(di),Xc=e.object({type:e.literal("ping")}),Yc=e.object({type:e.literal("visibility"),visible:e.boolean()}),BS=e.discriminatedUnion("type",[Kc,Vc,Xc,Yc]),zS=e.object({type:e.literal("pong")}).strict(),NS=e.object({type:e.literal("pong")});function Zc(n){throw new Error(`Unhandled realtime subscription target: ${n}`)}function zn(n){switch(n.kind){case"thread-detail":return`thread-detail:${n.threadId}`;case"thread-timeline":return`thread-timeline:${n.threadId}:${n.segmentLimit??"default"}:${n.deferContent?"deferred":"inline"}`;case"thread-list":return"thread-list";case"project-detail":return`project-detail:${n.projectId}`;case"project-list":return"project-list";case"environment-detail":return`environment-detail:${n.environmentId}`;case"environment-list":return"environment-list";case"host-detail":return`host-detail:${n.hostId}`;case"host-list":return"host-list";case"plugin":return`plugin:${n.pluginId}`;case"plugin-read":return`plugin-read:${kt({pluginId:n.pluginId,method:n.method,read:n.read})}`;case"system":return"system";default:return Zc(n)}}var ci=e.object({status:B,runtime:Be,activity:ze,latestAttentionAt:e.number(),updatedAt:e.number()}).strict(),ep=e.object({backgroundActivityChanged:e.boolean().optional(),eventTypes:e.array(gs).readonly().optional(),timelineSequence:e.number().int().nonnegative().optional(),hasPendingInteraction:e.boolean().optional(),projectId:e.string().optional(),statusChange:ci.optional()}).strict(),tp=e.object({type:e.literal("changed"),entity:e.literal("thread"),id:e.string().optional(),metadata:ep.optional(),changes:e.array(Nc).readonly()}).strict(),np=e.object({type:e.literal("changed"),entity:e.literal("project"),id:e.string().optional(),changes:e.array(Hc).readonly()}).strict(),rp=e.object({type:e.literal("changed"),entity:e.literal("environment"),id:e.string().optional(),changes:e.array(Fc).readonly()}).strict(),sp=e.object({type:e.literal("changed"),entity:e.literal("host"),id:e.string().optional(),changes:e.array(Wc).readonly()}).strict(),ip=e.object({type:e.literal("changed"),entity:e.literal("system"),changes:e.array($c).readonly()}).strict(),pi=e.object({type:e.literal("changed"),entity:e.literal("tags"),tags:e.array(e.string().min(1)).min(1)}).strict(),ui=e.object({type:e.literal("changed"),entity:e.literal("plugin"),pluginId:e.string().min(1),tags:e.array(e.string().min(1)).min(1).nullable()}).strict(),op=e.discriminatedUnion("entity",[tp,np,rp,sp,ip,pi,ui]);function Fe(n){let t=new Set(n);return e.array(e.string()).transform(r=>r.filter(s=>t.has(s)))}var ap=new Set(ut),lp=e.object({timelineSequence:e.number().int().nonnegative().optional(),backgroundActivityChanged:e.boolean().optional(),eventTypes:e.array(e.string()).transform(n=>n.filter(t=>ap.has(t))).optional(),hasPendingInteraction:e.boolean().optional(),projectId:e.string().optional(),statusChange:ci.optional().catch(void 0)}),dp=e.object({type:e.literal("changed"),entity:e.literal("thread"),id:e.string().optional(),metadata:lp.optional(),changes:Fe(ni)}),cp=e.object({type:e.literal("changed"),entity:e.literal("project"),id:e.string().optional(),changes:Fe(ri)}),pp=e.object({type:e.literal("changed"),entity:e.literal("environment"),id:e.string().optional(),changes:Fe(si)}),up=e.object({type:e.literal("changed"),entity:e.literal("host"),id:e.string().optional(),changes:Fe(ii)}),mp=e.object({type:e.literal("changed"),entity:e.literal("system"),changes:Fe(oi)}),mi=e.discriminatedUnion("entity",[dp,cp,pp,up,mp,pi.strip(),ui.strip()]);var hp=["connected","disconnected"],Nn=e.enum(hp),gp=e.object({phase:e.enum(["creating","active","suspending","suspended","resuming","removing","destroyed"]),suspendedAt:e.number().nullable(),message:e.string().nullable(),pendingLog:e.string(),teardown:e.object({status:e.enum(["running","failed","removed"]),attempt:e.number().int().nonnegative()}).nullable()}),Hn=e.enum(["persistent","ephemeral"]),hi=e.object({id:e.string(),name:e.string(),type:Hn,status:Nn,machineProviderId:e.string().nullable(),lifecycle:gp,maxPermissionMode:L,lastSeenAt:e.number().nullable(),lastRejectedProtocolVersion:e.number().int().positive().nullable(),createdAt:e.number(),updatedAt:e.number()});var fp=256*1024;function bp(n){return new TextEncoder().encode(n).byteLength>fp}var fe=je.superRefine((n,t)=>{bp(JSON.stringify(n))&&t.addIssue({code:"custom",message:"pluginMetadata exceeds 256 KiB"})});function gi(n,t){if(n===null||typeof n!="object")return;if(t.has(n))throw new Error("pluginMetadata contains a cycle");let r=Array.isArray(n);if(Object.getPrototypeOf(n)!==(r?Array.prototype:Object.prototype))throw new Error("pluginMetadata must contain plain JSON data");t.add(n);for(let s of r?n:Object.values(n))gi(s,t);t.delete(n)}function Pt(n){if(n===null||typeof n!="object"||Array.isArray(n))throw new Error("pluginMetadata must be a plain JSON object");return gi(n,new Set),fe.parse(n)}var Fn=/^[a-z0-9][a-z0-9-]*$/u,At=e.string().regex(Fn),We=e.string().regex(Fn),Wn=e.string().regex(Fn),fi=e.object({id:At,displayName:e.string().min(1),description:e.string().min(1)}),KS=e.object({id:We,displayName:e.string().min(1),pluginIds:e.array(Wn).superRefine((n,t)=>{let r=new Set;n.forEach((s,i)=>{r.has(s)&&t.addIssue({code:"custom",path:[i],message:`duplicate plugin id "${s}"`}),r.add(s)})})}),yp=[{id:"themes-and-appearance",displayName:"Themes & Appearance",description:"Personalize how bb looks and feels."},{id:"thread-management",displayName:"Thread Management",description:"Find, identify, organize, or archive threads."},{id:"thread-content",displayName:"Thread Content",description:"Change what people see or do inside an open thread."},{id:"memory-and-context",displayName:"Memory & Context",description:"Control durable knowledge or standing context available to agents."},{id:"security",displayName:"Security",description:"Protect credentials or prevent unsafe code."},{id:"agents-and-providers",displayName:"Agents & Providers",description:"Add, choose, configure, route, or coordinate who runs a thread."},{id:"environments",displayName:"Environments",description:"Create and manage the places where threads run."},{id:"token-usage-and-limits",displayName:"Token Usage & Limits",description:"Understand or control token, context-window, and provider-quota use."},{id:"notifications",displayName:"Notifications",description:"Know when work finished, failed, or needs attention."},{id:"code-and-reviews",displayName:"Code & Reviews",description:"Work with repositories, builds, changes, pull requests, issues, and reviews."},{id:"file-viewers-and-editors",displayName:"File Viewers & Editors",description:"Browse, open, preview, or edit files and document vaults."},{id:"cloud-and-remote",displayName:"Environments & Cloud",description:"Create and manage where threads run, locally or in the cloud."},{id:"command-line",displayName:"Command Line",description:"Work with shells and command-line programs inside bb."},{id:"utilities",displayName:"Utilities",description:"Inspect or control the computers bb runs on."},{id:"plugin-development",displayName:"Plugin Development",description:"Understand, inspect, build, or debug bb and its plugin surfaces."},{id:"tasks-and-workflows",displayName:"Tasks & Workflows",description:"Plan, track, route, schedule, or automate work."}],VS=new Map(yp.map(n=>[n.id,n]));var vp=/^([A-Za-z]):(?:[\\/]+|$)/u,yi=/^[\\/]{2}([^\\/]+)[\\/]+([^\\/]+)/u,bi=/[\\/]+/u;function $n(n){let t=[];for(let r of n)if(!(r.length===0||r===".")){if(r===".."){t.pop();continue}t.push(r)}return t}function It(n){let t=vp.exec(n);if(t)return{flavor:"windows",root:`${(t[1]??"").toUpperCase()}:\\`,segments:$n(n.slice(t[0].length).split(bi))};let r=yi.exec(n);return r?{flavor:"windows",root:`\\\\${r[1]??""}\\${r[2]??""}\\`,segments:$n(n.slice(r[0].length).split(bi))}:n.startsWith("/")?{flavor:"posix",root:"/",segments:$n(n.split("/"))}:null}function vi(n){return n.flavor==="posix"?`/${n.segments.join("/")}`:n.segments.length===0?n.root:`${n.root}${n.segments.join("\\")}`}function Si(n){return It(n)?.flavor??null}function Qn(n){return yi.test(n)}function xi(n){let t=It(n);return t!==null&&t.segments.length===0}function Ri(n){let t=It(n);return t===null?null:vi(t)}function Ti(n){let t=It(n);return t===null?n:t.flavor==="windows"?vi(t):n.replace(/\/+$/u,"")||"/"}var wi="Project path must be an absolute path.",Sp="Project path must point to a project directory, not the filesystem root.",xp="Windows network paths are not supported. Map the share to a drive letter and use a path like C:\\Users\\me\\repo.";function ki(n){return Si(n)==="windows"&&!Qn(n)}function Rp(n){let t=n.trim();return t?t.startsWith("/")||ki(t):!1}function Gn(n){let t=n.trim();return t?ki(t)?Ri(t)??t:t==="/"?t:t.replace(/\/+$/u,""):""}function Pi(n){let t=Gn(n);return t?Qn(t)?xp:Rp(t)?xi(t)?Sp:null:wi:wi}var Tp=["project","thread"],wp=e.enum(Tp),Jn=e.object({id:e.string().min(1),createdAt:e.number(),input:e.array(_).min(1)}),sx=Jn.extend({projectId:e.string().min(1),threadId:e.string().min(1),scope:wp});var kp=e.object({reasoningEffort:O,label:e.string().min(1).optional(),description:e.string()}),Pp=e.object({id:K,label:e.string().min(1).optional(),description:e.string().min(1).optional()}),Kn=e.object({id:e.string(),model:e.string(),displayName:e.string(),routeProviderId:e.string().min(1).optional(),description:e.string(),supportedReasoningEfforts:e.array(kp),defaultReasoningEffort:O,supportedServiceTiers:e.array(Pp).optional(),sessionOptions:e.array(_n).max(64).optional(),isDefault:e.boolean()}),Ap=e.enum(["host","workspace"]),Ip=e.object({supportsThreadArchive:e.boolean(),supportsThreadRename:e.boolean(),supportsServiceTier:e.boolean(),supportsNativeUserQuestion:e.boolean(),supportsFork:e.boolean(),supportsSessionRewind:e.boolean(),permissionModes:e.array(L).min(1),modelCatalogScope:Ap}),Ai=e.object({trigger:Tn,name:e.string().min(1).regex(/^[^\s/$]+$/u),trailingText:e.string().regex(/^\s*$/u)}),Ep=e.discriminatedUnion("kind",[e.object({kind:e.literal("skills"),trigger:Tn}),e.object({kind:e.literal("plan"),command:Ai}),e.object({kind:e.literal("goal"),command:Ai})]),Cp=e.object({signInHint:e.string().min(1),expiredHint:e.string().min(1),installUrl:e.string().min(1),brandPrefix:e.string().min(1).optional(),planModeCopy:e.string().min(1).optional(),iconTint:e.object({light:e.string().min(1),dark:e.string().min(1)}).optional()}),Ii=e.object({id:e.string().min(1),label:e.string().min(1),description:e.string().min(1).optional()}),jp=e.object({item:e.boolean(),state:e.boolean()}),_p=e.record(ft,jp),Vn=e.object({id:e.string(),pluginId:e.string().min(1),displayName:e.string(),family:e.string().min(1).optional(),icon:e.object({glyph:e.string().min(1)}).optional(),logoUrl:e.string().min(1).nullable(),maintenance:e.object({health:e.boolean(),usage:e.boolean(),installation:e.boolean()}),capabilities:Ip,composerActions:e.array(Ep),completedTurnDisplay:ue,available:e.boolean(),strings:Cp.optional(),serviceTiers:e.array(Ii).optional(),reasoningLevels:e.array(Ii).optional(),extensionKinds:_p.optional()}),Mp=["sessionArchived","authRequired","restartRecommended","staleTurn","rateLimited"],ux=e.enum(Mp),Dp=e.discriminatedUnion("type",[e.object({type:e.literal("inputText"),text:e.string()}),e.object({type:e.literal("inputImage"),imageUrl:e.string()})]),mx=e.object({requestId:e.union([e.string().min(1),e.number()]),threadId:e.string().min(1),providerThreadId:e.string().min(1),turnId:e.string().min(1),callId:e.string().min(1),tool:e.string().min(1),arguments:e.unknown().optional()}),hx=e.object({contentItems:e.array(Dp),success:e.boolean()}),gx=e.object({name:e.string(),description:e.string(),inputSchema:e.unknown(),presentation:gt.optional()});var Xn="23456789abcdefghijkmnpqrstuvwxyz",Yn=10,Op="thr_",Lp=`${Op}[${Xn}]{${Yn}}`,Ei=new RegExp(`^${Lp}$`,"u"),Zn=e.string().regex(Ei);function yx(n){return Ei.test(n)}var Et=e.discriminatedUnion("type",[e.object({type:e.literal("uncommitted")}),e.object({type:e.literal("branch_committed"),mergeBaseBranch:e.string().min(1)}),e.object({type:e.literal("all"),mergeBaseBranch:e.string().min(1)}),e.object({type:e.literal("commit"),sha:e.string().regex(/^[0-9a-f]{4,40}$/iu)})]),xx=e.object({path:e.string(),previousPath:e.string().nullable(),statusLetter:e.enum(["A","M","D","R","C","T"]),additions:e.number().int().nonnegative(),deletions:e.number().int().nonnegative(),binary:e.boolean(),origin:e.enum(["tracked","untracked"]),revision:e.string().min(1)}),Ci=e.object({diff:e.string(),truncated:e.boolean(),shortstat:e.string(),files:e.string(),mergeBaseRef:e.string().nullable()});var qp=["agent","system"],Up=e.enum(qp),ji=e.object({initiator:Up,senderThreadId:e.string().min(1)});var Bp=["title","title_fallback","user_message","assistant_message","system_message"],_i=e.enum(Bp);var Mi=e.object({mode:e.literal("plan"),providerId:e.string().min(1),prompt:e.string()}).strict();var Di=e.object({sourceSeq:e.number().int().nonnegative(),detectedAt:e.number(),originalModel:e.string().min(1),fallbackModel:e.string().min(1),reason:e.enum(["refusal","provider"]),message:e.string()});var zp=e.enum(["pending","in_progress","completed"]),Np=e.object({id:e.string(),text:e.string(),status:zp}),Oi=e.object({sourceSeq:e.number().int().nonnegative(),updatedAt:e.number(),items:e.array(Np)});var Li={ios:"https://testflight.apple.com/join/T9MayTMb",android:"https://github.com/get-bb/bb/releases/download/android-testing/bb-android.apk"};var Hp=e.string().regex(new RegExp(`^term_[${Xn}]{${Yn}}$`,"u")),Ct=e.object({id:e.string().min(1),threadId:e.string().min(1).nullable(),environmentId:e.string().min(1).nullable(),hostId:e.string().min(1),title:e.string().min(1),initialCwd:e.string().min(1),cols:Oe,rows:Le,status:Dn,exitCode:e.number().int().nullable(),closeReason:On.nullable(),createdAt:e.number().int().nonnegative(),updatedAt:e.number().int().nonnegative(),lastUserInputAt:e.number().int().nonnegative().nullable()}),Lx=e.object({sessions:e.array(Ct)}),qx=e.object({cwd:e.string().trim().min(1).optional(),environmentId:e.string().min(1).optional(),hostId:e.string().min(1).optional(),threadId:e.string().min(1).optional()}).strict().superRefine((n,t)=>{[n.threadId!==void 0,n.environmentId!==void 0,n.hostId!==void 0].filter(Boolean).length!==1&&t.addIssue({code:e.ZodIssueCode.custom,message:"Exactly one terminal scope must be provided: threadId, environmentId, or hostId"}),n.cwd!==void 0&&n.hostId===void 0&&t.addIssue({code:e.ZodIssueCode.custom,message:"cwd can only be provided with hostId"})}),er=e.discriminatedUnion("kind",[e.object({kind:e.literal("thread"),threadId:e.string().min(1)}).strict(),e.object({kind:e.literal("environment"),environmentId:e.string().min(1)}).strict(),e.object({kind:e.literal("host_path"),hostId:e.string().min(1),cwd:e.string().trim().min(1).nullable()}).strict()]),Ux=e.object({cols:Oe,id:Hp.optional(),rows:Le,start:e.discriminatedUnion("mode",[e.object({mode:e.literal("shell")}).strict(),e.object({mode:e.literal("command"),command:e.string().trim().min(1).max(1e4)}).strict(),e.object({mode:e.literal("argv"),argv:e.array(e.string().max(1e4)).min(1).max(256)}).strict()]).optional(),target:er,title:e.string().trim().min(1).max(200).optional()}).strict(),Bx=e.object({mode:e.enum(["force","if-clean"]),reason:e.literal("user")}).strict(),zx=e.object({}).strict(),Nx=e.object({title:e.string().trim().min(1).max(200)}).strict(),qi=e.object({seq:e.number().int().nonnegative(),dataBase64:xt}).strict(),Hx=e.object({dataBase64:xt}).strict(),Fx=e.object({cols:Oe,rows:Le}).strict(),Wx=e.object({sinceSeq:e.coerce.number().int().nonnegative().optional(),tailBytes:e.coerce.number().int().positive().max(4*1024*1024).optional(),limitChunks:e.coerce.number().int().positive().max(1e4).optional()}).strict(),$x=e.object({sinceSeq:e.coerce.number().int().nonnegative().default(0),outputAcks:e.enum(["0","1"]).default("0").transform(n=>n==="1")}).strict(),Qx=e.object({chunks:e.array(qi),nextSeq:e.number().int().nonnegative(),truncated:e.boolean(),status:Dn,exitCode:e.number().int().nullable(),closeReason:On.nullable()}).strict(),Gx=e.discriminatedUnion("type",[e.object({type:e.literal("input"),dataBase64:xt}).strict(),e.object({type:e.literal("resize"),cols:Oe,rows:Le}).strict(),e.object({type:e.literal("ping")}).strict(),e.object({type:e.literal("ack"),nextSeq:e.number().int().nonnegative()}).strict(),e.object({type:e.literal("visibility"),visible:e.boolean()}).strict()]),Jx=e.discriminatedUnion("type",[e.object({type:e.literal("attached"),session:Ct,replayStartSeq:e.number().int().nonnegative(),nextSeq:e.number().int().nonnegative()}).strict(),e.object({type:e.literal("output"),chunk:qi}).strict(),e.object({type:e.literal("session-updated"),session:Ct}).strict(),e.object({type:e.literal("exited"),session:Ct}).strict(),e.object({type:e.literal("error"),code:e.string().min(1),message:e.string().min(1)}).strict(),e.object({type:e.literal("pong")}).strict()]);var Fp=(n,t,r={})=>{let s=`${n}=${t}`;if(n.startsWith("__Secure-")&&!r.secure)throw new Error("__Secure- Cookie must have Secure attributes");if(n.startsWith("__Host-")){if(!r.secure)throw new Error("__Host- Cookie must have Secure attributes");if(r.path!=="/")throw new Error('__Host- Cookie must have Path attributes with "/"');if(r.domain)throw new Error("__Host- Cookie must not have Domain attributes")}if(r&&typeof r.maxAge=="number"&&r.maxAge>=0){if(r.maxAge>3456e4)throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");s+=`; Max-Age=${r.maxAge|0}`}if(r.domain&&r.prefix!=="host"&&(s+=`; Domain=${r.domain}`),r.path&&(s+=`; Path=${r.path}`),r.expires){if(r.expires.getTime()-Date.now()>3456e7)throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");s+=`; Expires=${r.expires.toUTCString()}`}if(r.httpOnly&&(s+="; HttpOnly"),r.secure&&(s+="; Secure"),r.sameSite&&(s+=`; SameSite=${r.sameSite.charAt(0).toUpperCase()+r.sameSite.slice(1)}`),r.priority&&(s+=`; Priority=${r.priority.charAt(0).toUpperCase()+r.priority.slice(1)}`),r.partitioned){if(!r.secure)throw new Error("Partitioned Cookie must have Secure attributes");s+="; Partitioned"}return s},Ui=(n,t,r)=>(t=encodeURIComponent(t),Fp(n,t,r));var Bi=(n,t)=>(n=n.replace(/\/+$/,""),n=n+"/",t=t.replace(/^\/+/,""),n+t),_t=(n,t)=>{for(let[r,s]of Object.entries(t)){let i=new RegExp("/:"+r+"(?:{[^/]+})?\\??");n=n.replace(i,s?`/${s}`:"")}return n},zi=n=>{let t=new URLSearchParams;for(let[r,s]of Object.entries(n))if(s!==void 0)if(Array.isArray(s))for(let i of s)t.append(r,i);else t.set(r,s);return t},Ni=(n,t)=>{switch(t){case"ws":return n.replace(/^http/,"ws");case"http":return n.replace(/^ws/,"http")}},tr=n=>/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test(n)?n.replace(/\/index(?=\?|$)/,"/"):n.replace(/\/index(?=\?|$)/,"");function jt(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function nr(n,t){if(!jt(n)&&!jt(t))return t;let r={...n};for(let s in t){let i=t[s];jt(r[s])&&jt(i)?r[s]=nr(r[s],i):r[s]=i}return r}var Hi=(n,t)=>new Proxy(()=>{},{get(s,i){if(!(typeof i!="string"||i==="then"))return Hi(n,[...t,i])},apply(s,i,a){return n({path:t,args:a})}}),$p=class{url;method;buildSearchParams;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor(n,t,r){this.url=n,this.method=t,this.buildSearchParams=r.buildSearchParams}fetch=async(n,t)=>{if(n){if(n.query&&(this.queryParams=this.buildSearchParams(n.query)),n.form){let p=new FormData;for(let[m,o]of Object.entries(n.form))if(Array.isArray(o))for(let g of o)p.append(m,g);else p.append(m,o);this.rBody=p}n.json&&(this.rBody=JSON.stringify(n.json),this.cType="application/json"),n.param&&(this.pathParams=n.param)}let r=this.method.toUpperCase(),s={...n?.header,...typeof t?.headers=="function"?await t.headers():t?.headers};if(n?.cookie){let p=[];for(let[m,o]of Object.entries(n.cookie))p.push(Ui(m,o,{path:"/"}));s.Cookie=p.join(",")}this.cType&&(s["Content-Type"]=this.cType);let i=new Headers(s??void 0),a=this.url;a=tr(a),a=_t(a,this.pathParams),this.queryParams&&(a=a+"?"+this.queryParams.toString()),r=this.method.toUpperCase();let l=!(r==="GET"||r==="HEAD");return(t?.fetch||fetch)(a,{body:l?this.rBody:void 0,method:r,headers:i,...t?.init})}},$e=(n,t)=>Hi(function r(s){let i=t?.buildSearchParams??zi,a=[...s.path],l=a.slice(-3).reverse();if(l[0]==="toString")return l[1]==="name"?l[2]||"":r.toString();if(l[0]==="valueOf")return l[1]==="name"?l[2]||"":r;let p="";if(/^\$/.test(l[0])){let h=a.pop();h&&(p=h.replace(/^\$/,""))}let m=a.join("/"),o=Bi(n,m);if(p==="url"){let h=o;return s.args[0]&&(s.args[0].param&&(h=_t(o,s.args[0].param)),s.args[0].query&&(h=h+"?"+i(s.args[0].query).toString())),h=tr(h),new URL(h)}if(p==="ws"){let h=Ni(s.args[0]&&s.args[0].param?_t(o,s.args[0].param):o,"ws"),b=new URL(h),y=s.args[0]?.query;return y&&Object.entries(y).forEach(([u,f])=>{Array.isArray(f)?f.forEach(v=>b.searchParams.append(u,v)):b.searchParams.set(u,f)}),((...u)=>t?.webSocket!==void 0&&typeof t.webSocket=="function"?t.webSocket(...u):new WebSocket(...u))(b.toString())}let g=new $p(o,p,{buildSearchParams:i});if(p){t??={};let h=nr(t,{...s.args[1]});return g.fetch(s.args[0],h)}return g},[]);function Qp(n){if(n!==void 0)return{fetch:n.fetch}}function Gp(n,t){return $e(`${n}/api/v1`,Qp(t))}function Fi(n,t){return{api:{v1:Gp(n,t)}}}function Qe(n){return n.value.split(",").every(r=>r.length>0&&n.allowedValues.includes(r))}var rr=e.object({snapshot:as.optional(),usedTokens:e.number(),modelContextWindow:e.number(),estimated:e.boolean(),cost:Rs.optional(),compactionOfferAt:e.iso.datetime().optional()}),bR=e.object({usage:rr.nullable()});var Kp=e.discriminatedUnion("kind",[e.object({kind:e.literal("existing"),name:M}).strict(),e.object({kind:e.literal("new"),baseBranch:M}).strict()]),Vp=e.object({type:e.literal("unmanaged"),path:e.string().min(1).transform(Ti).nullable(),branch:Kp.optional()}),Xp=e.object({type:e.literal("managed-worktree"),baseBranch:Es}),Yp=e.object({type:e.literal("personal")}),Zp=e.discriminatedUnion("type",[Vp,Xp,Yp]),sr=e.object({type:e.literal("reuse"),environmentId:e.string().min(1)}),Wi=e.object({type:e.literal("host"),hostId:e.string().min(1).optional(),workspace:Zp}).superRefine((n,t)=>{n.workspace.type!=="personal"&&n.hostId===void 0&&t.addIssue({code:"custom",message:"hostId is required unless workspace.type is personal",path:["hostId"]})}),yR=e.discriminatedUnion("type",[sr,Wi]),eu=e.object({type:e.literal("project-default")}),tu=e.object({type:e.literal("provider"),environmentProviderId:e.string().min(1),machine:e.discriminatedUnion("type",[e.object({type:e.literal("existing"),hostId:e.string().min(1)}),e.object({type:e.literal("new"),machineProviderId:e.string().min(1),inputs:S.nullable().default(null)})]).optional(),inputs:S.nullable().default(null)}),$i=e.string().min(1).max(128),vR=e.discriminatedUnion("type",[sr,e.object({type:e.literal("host"),hostId:e.string().min(1),path:e.string().min(1),mergeBaseBranch:M.optional(),ownsPath:e.boolean().default(!0)})]),ir=e.discriminatedUnion("type",[sr,Wi,eu,tu]),z=e.enum(["true","false"]),Mt=e.object({query:e.string().min(1).max(256).optional(),limit:e.string().regex(/^\d+$/).optional()});var Qi=mi,SR=e.object({type:e.literal("plugin-signal"),pluginId:e.string().min(1),channel:e.string().min(1),payload:e.unknown()}).strict(),xR=e.object({type:e.literal("plugin-signal"),pluginId:e.string().min(1),channel:e.string().min(1),payload:e.unknown()}),nu=e.object({path:e.string(),name:e.string()}),ru=e.enum(["file","directory"]),su=e.object({kind:ru,path:e.string(),name:e.string(),score:e.number(),positions:e.array(e.number().int().nonnegative())}),Gi=e.object({files:e.array(nu),truncated:e.boolean()}),Ji=e.object({paths:e.array(su),truncated:e.boolean()});function V(n,t){n.environmentId!==void 0&&n.hostId!==void 0&&t.addIssue({code:"custom",message:"hostId and environmentId are mutually exclusive"})}var or=e.string().trim().min(1).transform(Gn).superRefine((n,t)=>{let r=Pi(n);r&&t.addIssue({code:e.ZodIssueCode.custom,message:r})}),Vi=e.object({hostId:e.string().min(1),type:e.literal("local_path"),path:or}).strict(),iu=e.object({hostId:e.string().min(1),type:e.literal("clone"),targetPath:or.optional(),remoteUrl:e.string().trim().min(1).optional()}).strict(),PR=e.discriminatedUnion("type",[Vi,iu]),AR=e.object({name:e.string().min(1),source:Vi}),Dt=e.object({id:e.string(),name:e.string().min(1),createdAt:e.number(),updatedAt:e.number()}).strict(),IR=e.object({name:e.string().min(1)}).strict(),ER=e.object({id:e.string().min(1),name:e.string().min(1)}).strict(),CR=e.object({id:e.string().min(1)}).strict(),ar=e.object({id:e.string().min(1),name:e.string().min(1),updatedThreadCount:e.number().int().nonnegative()}).strict(),jR=e.object({previousProjectId:e.string().min(1).nullable(),nextProjectId:e.string().min(1).nullable()}),ou=e.enum(["threads"]),_R=e.object({include:e.string().min(1).refine(n=>Qe({allowedValues:ou.options,value:n}),{message:"Invalid include"}).optional(),includePersonal:e.enum(["true","false"]).optional()}),Ot={hostId:e.string().min(1),environmentId:e.preprocess(n=>n===""?void 0:n,e.string().min(1).optional())},MR=e.object(Ot).partial().superRefine(V),DR=e.object({...Ot,query:e.string().min(1).max(256).optional(),limit:e.string().regex(/^\d+$/).optional()}).partial().superRefine(V),OR=e.object({...Ot,query:e.string().min(1).max(256).optional(),limit:e.string().regex(/^\d+$/).optional(),includeFiles:z,includeDirectories:z}).partial({hostId:!0,environmentId:!0,query:!0,limit:!0}).superRefine(V),LR=Mt.extend({hostId:e.string().min(1),selectedBranch:M.optional()}).strict(),qR=js.extend({defaultWorktreeBaseBranch:e.string().min(1).nullable()}),UR=e.object({path:e.string().min(1)}),BR=e.object({}),zR=e.object({limit:e.string().regex(/^\d+$/)}).partial(),NR=e.array(Jn),HR=e.object({name:e.string().min(1)}).partial().refine(n=>n.name!==void 0,"At least one field must be provided"),FR=e.object({type:e.literal("local_path"),path:or.optional(),isDefault:e.literal(!0).optional()}).strict().refine(n=>n.path!==void 0||n.isDefault!==void 0,"At least one field besides type must be provided"),au=e.enum(["skill","command"]),lu=e.enum(["builtin","project","user"]),lr=e.object({name:e.string(),source:au,origin:lu,description:e.string().nullable(),argumentHint:e.string().nullable(),pluginId:e.string().min(1).optional()});var WR=e.object({commands:e.array(lr)}),$R=e.object({...Ot,provider:e.string().min(1)}).partial({hostId:!0,environmentId:!0}).strict().superRefine(V),du=e.enum(["bb-builtin","bb-user","bb-project","provider-user","provider-project","shared-user","shared-project","plugin"]),cu=e.string().min(1),Lt=e.string().regex(/^skill_[a-f0-9]{64}$/u),Xi=e.string().regex(/^[a-f0-9]{64}$/u),pu=e.object({id:Lt,name:e.string(),description:e.string().nullable(),provider:cu.nullable(),scope:du,pluginId:e.string().min(1).nullable(),filePath:e.string(),manageable:e.boolean(),registrySkillId:e.string().min(1).nullable()}),QR=e.object({skills:e.array(pu)}),GR=e.object({environmentId:e.preprocess(n=>n===""?null:n,e.string().min(1).nullable())}),JR=e.enum(["bb-user","bb-project","provider-user","provider-project"]),KR=e.object({skillId:Lt,environmentId:e.string().min(1).nullable()}).strict(),uu=e.object({skillId:Lt,environmentId:e.preprocess(n=>n===""?null:n,e.string().min(1).nullable())}),VR=uu.extend({path:e.string().min(1).max(4096)}),XR=e.object({content:e.string(),revision:Xi}),YR=e.object({files:e.array(e.string().min(1)),truncated:e.boolean()}),ZR=e.object({skillId:Lt,environmentId:e.string().min(1).nullable(),content:e.string().min(1).max(1e6),revision:Xi}).strict(),mu=Fs.extend({sources:e.array(Ws)}),Ki=mu.extend({threads:e.array(Ne),defaultExecutionOptions:ps.nullable()}),eT=e.object({sections:e.array(Dt),projects:e.array(Ki),personalProject:Ki}),Yi=e.object({sourceProjectId:e.string().min(1).optional(),type:e.enum(["localImage","localFile"]),path:e.string(),name:e.string(),mimeType:e.string().optional(),sizeBytes:e.number()}),tT=e.object({sourceProjectId:e.string().min(1),paths:e.array(e.string().min(1)).min(1).max(100)}).strict();var qt=e.object({id:e.string().min(1),source:e.string().min(1),skillId:e.string().min(1),name:e.string().min(1),installs:e.number().int().nonnegative(),stars:e.number().int().nonnegative().nullable(),installUrl:e.string().url().nullable(),url:e.string().url(),topic:e.string().nullable(),summary:e.string().nullable()}),hu=e.object({page:e.number().int().nonnegative(),perPage:e.number().int().positive(),total:e.number().int().nonnegative(),hasMore:e.boolean()}),gu=e.enum(["trending","all-time"]),Zi=e.object({skills:e.array(qt),pagination:hu,ranking:gu}),eo=e.object({stars:e.number().int().nonnegative()}),fu=e.object({path:e.string().min(1),contents:e.string()}),to=e.object({id:e.string().min(1),source:e.string().min(1),skillId:e.string().min(1),hash:e.string().nullable(),files:e.array(fu).nullable()}),no=e.object({ids:e.array(e.string().min(1)).min(1).max(200)}).strict(),ro=e.object({entries:e.array(qt)}),so=e.object({registrySkillId:e.string().min(1)}).strict(),io=e.object({ok:e.literal(!0),filePath:e.string().min(1)});var bu=e.enum(["path_not_found","not_git_repo","workspace_type_mismatch","permission_denied","unknown_environment","unknown"]),ye=e.object({code:bu,workspacePath:e.string().min(1),message:e.string().min(1)}).strict();var q=e.object({code:e.string().min(1),message:e.string(),details:e.unknown().optional(),retryable:e.boolean().optional()}),yu=e.object({environmentStatus:me,hasPath:e.boolean()}),vu=e.enum(["archived","stopping","deleted","not_started","not_active","errored","already_active","still_starting"]),Su=e.object({reason:vu,archivedAt:e.number().int().nonnegative().nullable(),threadStatus:B}),xu=e.enum(["never_attached","destroyed","provisioning","errored"]),Ru=e.object({reason:xu,environmentStatus:me.nullable()}),Tu=e.enum(["suspended","disconnected","destroyed"]),wu=e.object({reason:Tu,hostStatus:Nn.nullable(),suspendedAt:e.number().int().nonnegative().nullable(),destroyedAt:e.number().int().nonnegative().nullable()}),ku=e.enum(["deleted","pending_deletion"]),Pu=e.object({reason:ku,deletedAt:e.number().int().nonnegative().nullable()}),Au=e.enum(["not_found","archived","deleted","self","cycle","too_deep"]),Iu=e.enum(["parent","sender"]),Eu=e.object({reason:Au,subject:Iu}),oo=e.object({pluginId:k}),Cu=q.extend({code:e.literal("environment_not_ready"),details:yu}),ju=q.extend({code:e.literal("thread_not_writable"),details:Su}),_u=q.extend({code:e.literal("thread_environment_unavailable"),details:Ru}),Mu=q.extend({code:e.literal("host_unavailable"),details:wu}),Du=q.extend({code:e.literal("project_unavailable"),details:Pu}),Ou=q.extend({code:e.literal("parent_thread_invalid"),details:Eu}),Lu=q.extend({code:e.literal("dispatch_rejected"),details:oo}),qu=q.extend({code:e.literal("dispatch_hook_failed"),details:oo}),cT=e.discriminatedUnion("code",[Cu,ju,_u,Mu,Du,Ou,Lu,qu]);var bT=e.object({recover:e.enum(["true","false"]).default("false")}),Uu=e.string().trim().min(1).max(80),lo=e.object({mergeBaseBranch:M.nullable(),name:Uu.nullable()}).partial().refine(n=>n.mergeBaseBranch!==void 0||n.name!==void 0,"At least one field must be provided"),yT=e.object({projectId:e.string().min(1).optional(),environmentProviderId:e.string().min(1).optional(),hostId:e.string().min(1).optional(),instanceKey:$i.optional(),path:e.string().min(1).optional(),status:me.optional(),limit:e.string().regex(/^\d+$/).optional(),offset:e.string().regex(/^\d+$/).optional()}),vT=e.object({query:e.string().min(1).max(256).optional(),limit:e.string().regex(/^\d+$/).optional(),includeFiles:z,includeDirectories:z}),ST=Mt.extend({selectedBranch:M.optional()});var dr=e.string("A merge base branch is required").pipe(M),xT=e.object({mergeBaseBranch:dr.optional()}),co=e.discriminatedUnion("target",[e.object({target:e.literal("uncommitted")}),e.object({target:e.literal("branch_committed"),mergeBaseBranch:dr}),e.object({target:e.literal("all"),mergeBaseBranch:dr}),e.object({target:e.literal("commit"),sha:e.string().regex(/^[0-9a-f]{4,40}$/iu)})]),RT=co.and(e.object({ignoreWhitespace:e.enum(["true","false"]).optional()})),Ut=e.enum(["old","new"]),ao=e.string().regex(/^[0-9a-f]{4,40}$/iu),TT=e.discriminatedUnion("target",[e.object({target:e.literal("uncommitted"),path:e.string().min(1),side:Ut}),e.object({target:e.literal("branch_committed"),mergeBaseRef:ao,path:e.string().min(1),side:Ut}),e.object({target:e.literal("all"),mergeBaseRef:ao,path:e.string().min(1),side:Ut}),e.object({target:e.literal("commit"),sha:e.string().regex(/^[0-9a-f]{4,40}$/iu),path:e.string().min(1),side:Ut})]),wT=e.object({path:e.string(),content:e.string(),contentEncoding:e.enum(["base64","utf8"]),mimeType:e.string().optional(),sizeBytes:e.number().int().nonnegative()}),kT=e.object({ok:e.literal(!0),archivedThreadIds:e.array(e.string().min(1))}),PT=e.discriminatedUnion("action",[e.object({action:e.literal("commit")}).strict()]),cr=e.object({ok:e.literal(!0),action:e.literal("commit"),message:e.string().min(1),commitSha:e.string().min(1),commitSubject:e.string().min(1)}),AT=e.discriminatedUnion("action",[cr]),Bu=e.object({kind:e.literal("workspace_unavailable"),failure:ye}),IT=q.extend({details:Bu.optional()}),zu=e.enum(["non_git_environment"]),Bt=e.object({outcome:e.literal("not_applicable"),reason:zu,message:e.string().min(1)}).strict(),ET=e.discriminatedUnion("outcome",[e.object({outcome:e.literal("available"),workspace:ti}).strict(),Bt,e.object({outcome:e.literal("unavailable"),failure:ye}).strict()]),CT=e.discriminatedUnion("outcome",[e.object({outcome:e.literal("available"),diff:Ci}).strict(),Bt,e.object({outcome:e.literal("unavailable"),failure:ye}).strict()]),Nu=e.enum(["added","modified","deleted","renamed","copied","type_changed"]);var Hu=50,Fu=e.object({path:e.string(),previousPath:e.string().nullable(),changeKind:Nu,additions:e.number().int().nonnegative(),deletions:e.number().int().nonnegative(),binary:e.boolean(),origin:e.enum(["tracked","untracked"]),loadMode:e.enum(["auto","on_demand","too_large"]),revision:e.string().min(1)}),po=e.object({path:e.string(),patch:e.string(),truncated:e.boolean()}),jT=e.discriminatedUnion("outcome",[e.object({outcome:e.literal("available"),files:e.array(Fu),truncated:e.boolean(),shortstat:e.string(),mergeBaseRef:e.string().nullable(),initialPatches:e.array(po)}).strict(),Bt,e.object({outcome:e.literal("unavailable"),failure:ye}).strict()]),_T=e.discriminatedUnion("outcome",[e.object({outcome:e.literal("available"),patches:e.array(po)}).strict(),Bt,e.object({outcome:e.literal("unavailable"),failure:ye}).strict()]),MT=e.object({target:Et,paths:e.array(e.string().min(1)).min(1).max(Hu),ignoreWhitespace:e.boolean().optional()}).strict(),Wu=e.object({path:e.string().min(1),revision:e.string().min(1)}).strict(),DT=e.object({files:e.array(Wu)}).strict(),OT=co.and(e.object({paths:e.array(e.string().min(1).max(4096)).max(500)})),LT=e.object({target:Et,path:e.string().min(1).max(4096),revision:e.string().min(1).max(1024)}).strict(),qT=e.object({target:Et,path:e.string().min(1).max(4096).optional()}).strict();var mo="127.0.0.1";var ho=e.string().trim().min(1).max(200),uo=e.object({openDirectory:e.boolean(),openFile:e.boolean(),openFileAtLine:e.boolean(),openFileAtColumn:e.boolean().optional()}),$u=["editor","file-manager","terminal","default-app","native-app"],Qu=e.enum($u),Gu=2e5,Ju=e.discriminatedUnion("kind",[e.object({kind:e.literal("builtin"),name:e.string().trim().min(1).max(100)}).strict(),e.object({kind:e.literal("data-url"),dataUrl:e.string().trim().startsWith("data:image/").max(Gu)}).strict(),e.object({kind:e.literal("symbol"),name:e.enum(["default-app","file-manager","terminal","app"])}).strict()]),Ku=e.object({id:ho,label:e.string().min(1),kind:Qu.optional(),icon:Ju.optional(),capabilities:uo,remoteSshCapabilities:uo.optional()}),NT=e.object({targets:e.array(Ku)}),HT=e.object({path:e.string().min(1).optional()}),Vu=e.string().min(1),Xu=e.number().int().positive().nullable(),Yu=e.number().int().positive().nullable(),Zu=e.object({kind:e.literal("local")}).strict(),em=e.object({kind:e.literal("remote-ssh"),serverOrigin:e.string().url(),hostId:e.string().min(1)}).strict(),tm=e.discriminatedUnion("kind",[Zu,em]),FT=e.object({context:tm.default({kind:"local"}),columnNumber:Yu.default(null),lineNumber:Xu,path:Vu,targetId:ho}),WT=e.object({path:e.string().nullable()}),nm=200,rm=e.object({paths:e.array(e.string().min(1)).min(1).max(nm).transform(n=>Array.from(new Set(n)))}),$T=e.object({existence:e.record(e.string(),e.boolean())}),pr=e.enum(["darwin","linux","wsl","win32","unknown"]),QT=e.object({hostId:e.string().min(1),connected:e.boolean(),protocolVersion:e.number().int().positive(),serverUrl:e.string(),supportsNativeFolderPicker:e.boolean(),platform:pr}),GT=e.string().min(1),Ge=e.string().min(1),sm=["stdout","stderr"],im=e.enum(sm),om=["notInstalled","npmGlobal","external"],am=e.enum(om),lm=["install","update"],go=e.enum(lm),dm=e.object({kind:go,label:e.enum(["Install","Update"]),command:e.string().min(1)}),cm=e.object({displayName:e.string().min(1),executableName:e.string().min(1),executablePath:e.string().min(1).nullable(),installed:e.boolean(),installSource:am,currentVersion:e.string().min(1).nullable(),latestVersion:e.string().min(1).nullable(),minimumSupportedVersion:e.string().min(1).nullable(),npmPackageName:e.string().min(1).nullable(),npmGlobalPackageVersion:e.string().min(1).nullable(),installAction:dm.nullable(),needsUpdate:e.boolean(),versionUnsupported:e.boolean()}),JT=e.record(e.string().min(1),cm),pm=e.object({provider:Ge,actionKind:go}),um=e.object({type:e.literal("started"),provider:Ge,command:e.string().min(1)}),mm=e.object({type:e.literal("output"),provider:Ge,stream:im,text:e.string()}),hm=e.object({type:e.literal("completed"),provider:Ge,exitCode:e.number().int().nullable(),signal:e.string().min(1).nullable(),success:e.boolean()}),gm=e.object({type:e.literal("error"),provider:Ge,message:e.string().min(1)}),fo=e.discriminatedUnion("type",[um,mm,hm,gm]);function bo(n){let t=n.replace(/\/$/,"");return $e(t)}var ZT=e.object({path:e.string().min(1).optional()}),fm=e.object({kind:e.enum(["file","directory"]),name:e.string(),path:e.string()}),ew=e.object({directory:e.string(),parent:e.string().nullable(),entries:e.array(fm),roots:e.array(e.string())}),bm=e.object({path:e.string().min(1),name:e.string().min(1),lastActivityAt:e.string().datetime(),originUrl:e.string().min(1).nullable(),projectId:e.string().min(1).nullable()}),tw=e.object({repos:e.array(bm),truncated:e.boolean()}),nw=e.object({projectId:e.string().min(1)}),rw=e.object({path:e.string().min(1)}).strict(),sw=e.object({}).strict(),iw=e.object({machineProviderId:e.string().min(1),inputs:S.nullable(),key:e.string().min(1).optional()}).strict(),ow=e.object({command:e.string().min(1),windowsCommand:e.string().min(1),expiresAt:e.number().int().positive()}).nullable(),aw=e.object({command:e.string().min(1),windowsCommand:e.string().min(1),expiresAt:e.number().int().positive(),hostId:e.string().min(1)}).strict(),lw=e.object({joinCode:e.string().min(1),hostId:e.string().min(1),expiresAt:e.number().int().positive()}),dw=e.object({name:e.string().trim().min(1).max(100)}).strict(),cw=e.object({maxPermissionMode:L}).strict(),pw=e.object({ok:e.literal(!0)}).strict();var uw=e.object({clientHostId:e.string().min(1)}).strict();var yo=fo,mw=e.object({includeCreating:e.enum(["true","false"]).optional(),type:Hn.optional()}),hw=e.object({force:e.enum(["true","false"]).optional()});var ym=e.enum(["starting","running","error","incompatible","missing","disabled","degraded","needs-configuration"]),vo=e.enum(["current","update-available","pinned","incompatible","unavailable"]),Nt=e.object({version:e.string(),display:e.string()}),vm=e.object({id:e.string(),outcome:vo,devMode:e.literal(!0).optional(),installed:Nt,candidate:Nt.optional(),blocked:e.object({version:e.string(),reasons:e.array(e.string())}).optional(),detail:e.string().optional()}),So=e.object({id:e.string().min(1).optional()}).strict(),ur=e.object({results:e.array(vm)}),xo=e.object({}).strict(),mr=e.object({applied:e.boolean(),from:Nt,to:Nt.optional(),outcome:e.enum(["current","updated","rolled-back"]),detail:e.string().optional()}),Sm=e.enum(["preparing","activating","checking","rolling-back"]),zt={id:e.string().min(1),pluginId:e.string().min(1),displayName:e.string().min(1)},Ro=e.discriminatedUnion("state",[e.object({...zt,state:e.literal("queued")}),e.object({...zt,state:e.literal("running"),phase:Sm}),e.object({...zt,state:e.literal("completed"),result:mr}),e.object({...zt,state:e.literal("failed"),error:e.string()})]),hr=e.object({job:Ro}),To=e.object({jobs:e.array(Ro)}),xm=e.object({version:e.string(),activatedAt:e.number()}),wo=e.object({requested:e.string(),resolved:e.string(),subdirectory:e.string().optional(),range:e.string().optional(),tagPrefix:e.string().optional(),resolvedTag:e.string().optional(),integrity:e.string().optional(),registry:e.string().optional(),engines:e.object({bb:e.string().optional(),bbPluginSdk:e.string().optional()}),installedAt:e.number().optional(),history:e.array(xm)}),Rm=e.object({outcome:vo.optional(),detail:e.string().optional(),availableVersion:e.string().optional(),blockedVersion:e.string().optional(),blockedReasons:e.array(e.string()).optional(),lastCheckAt:e.number().optional(),lastFailure:e.object({version:e.string(),at:e.number(),detail:e.string()}).optional()}),Tm=e.object({count:e.number(),totalMs:e.number(),maxMs:e.number(),errorCount:e.number()}),wm=e.object({name:e.string(),state:e.enum(["running","backoff","stopped"])}),km=e.object({name:e.string(),cron:e.string(),nextRunAt:e.number(),lastRunAt:e.number().nullable(),lastStatus:e.enum(["running","ok","error"]).nullable(),lastError:e.string().nullable()}),Pm=e.object({hasApp:e.boolean(),bundle:e.object({jsUrl:e.string(),cssUrl:e.string().nullable(),jsBytes:e.number().int().nonnegative(),hash:e.string(),sdkMajor:e.number(),sdkVersion:e.string(),compatible:e.boolean()}).nullable()}),Am=e.object({kind:e.enum(["skill","theme","agent-tool","thread-integration"]),id:e.string(),label:e.string(),detail:e.string().nullable()}),Im=e.array(Am),Z=e.object({id:e.string(),source:e.string(),rootDir:e.string(),version:e.string(),provenance:e.enum(["builtin","direct","catalog"]),isOrphanedBuiltin:e.boolean(),catalogEntryId:e.string().optional(),catalogMarketplaceName:e.string().optional(),publisherLabel:e.string().nullable().default(null),sourceDisplay:e.string(),updateState:Rm,enabled:e.boolean(),description:e.string().nullable(),name:e.string().nullable(),categoryId:At.optional(),category:e.string().optional(),screenshots:e.array(e.string()),collections:e.array(e.object({id:We,rank:e.number().int().nonnegative()})),publishedAt:e.iso.datetime({offset:!0}).optional(),updatedAt:e.iso.datetime({offset:!0}).optional(),icon:e.string().nullable(),iconUrl:e.string().nullable(),status:ym,statusDetail:e.string().nullable(),handlerStats:Tm,services:e.array(wm),schedules:e.array(km),cliCommand:e.object({name:e.string(),summary:e.string()}).nullable(),capabilities:Im.default([]),hasSettings:e.boolean(),app:Pm,logoUrl:e.string().nullable(),logoDarkUrl:e.string().nullable(),providerIds:e.array(e.string()),icons:e.record(e.string(),e.string())}),yw=e.object({plugins:e.array(Z)}),ko=e.discriminatedUnion("kind",[e.object({kind:e.literal("root")}).strict(),e.object({kind:e.literal("subdirectory"),path:e.string().min(1)}).strict(),e.object({kind:e.literal("entry"),name:e.string().min(1)}).strict()]),Em={kind:"root"},Po=e.object({source:e.string().min(1),selection:ko.default(Em)}).strict(),Cm=/^[a-z0-9][a-z0-9-]*$/u;var Ke=e.string().min(1).max(64).regex(Cm),Ht=e.object({entryId:e.string().min(1),marketplace:Ke.optional(),confirmedSource:e.lazy(()=>zo).optional()}).strict(),jm=e.discriminatedUnion("kind",[e.object({kind:e.literal("catalog"),entryId:e.string().min(1),marketplace:Ke}).strict(),e.object({kind:e.literal("source"),source:e.string().min(1),selection:ko}).strict()]),ve={id:e.string().min(1),target:jm,displayName:e.string().min(1)},gr=e.discriminatedUnion("state",[e.object({...ve,state:e.literal("queued")}),e.object({...ve,state:e.literal("running")}),e.object({...ve,state:e.literal("cancelling")}),e.object({...ve,state:e.literal("succeeded"),plugin:Z}),e.object({...ve,state:e.literal("failed"),error:e.string()}),e.object({...ve,state:e.literal("cancelled")})]),Ao=e.object({ok:e.literal(!0),job:gr}),fr=e.object({job:gr}),Io=e.object({jobs:e.array(gr)}),vw=e.object({ok:e.literal(!0),plugins:e.array(Z)}),Eo=e.object({ok:e.literal(!0)}),Je={label:e.string().min(1),description:e.string().min(1).optional()},_m=e.discriminatedUnion("type",[e.object({...Je,type:e.literal("string"),secret:e.literal(!0).optional(),experimental_multiline:e.boolean().optional(),default:e.string().optional()}).strict(),e.object({...Je,type:e.literal("boolean"),default:e.boolean().optional()}).strict(),e.object({...Je,type:e.literal("number"),default:e.number().finite().optional()}).strict(),e.object({...Je,type:e.literal("select"),options:e.array(e.string().min(1)).min(1),experimental_optionLabels:e.record(e.string().min(1),e.string().min(1)).optional(),default:e.string().optional()}).strict(),e.object({...Je,type:e.literal("project"),default:e.string().optional()}).strict()]),br=e.object({ok:e.literal(!0),schema:e.record(e.string(),_m),values:e.record(e.string(),S)}),Co=e.object({values:e.record(e.string(),S)}).strict(),jo=e.object({enabled:e.boolean()}).strict(),_o=e.object({enabled:e.boolean()}),Mo=e.object({enabled:e.boolean(),problems:e.array(e.string())}),Do=e.object({dryRun:e.boolean().optional().default(!1)}).strict(),Mm=e.object({pluginId:e.string().nullable(),version:e.string(),path:e.string(),bytes:e.number().int().nonnegative()}),Oo=e.object({dryRun:e.boolean(),removed:e.array(Mm),bytes:e.number().int().nonnegative()}),Lo=e.object({rotate:e.boolean().optional().default(!1)}).strict(),qo=e.object({ok:e.literal(!0),token:e.string()}),Dm=e.object({pluginCount:e.number(),includedPluginCount:e.number(),optionalPluginCount:e.number()}),Uo=e.object({catalog:Dm}),Bo=e.object({name:e.string(),github:e.string().nullable().default(null),url:e.string().nullable()}),Om=e.object({id:We,rank:e.number().int().nonnegative()}),Lm=e.object({id:We,displayName:e.string(),pluginIds:e.array(Wn)}),qm=e.object({entryId:e.string(),pluginId:e.string(),displayName:e.string(),description:e.string(),icon:e.string().nullable(),iconUrl:e.string().nullable(),iconTinted:e.boolean().default(!1),categoryId:At.optional(),category:e.string().optional(),screenshots:e.array(e.string()).default([]),overview:e.string().optional(),collections:e.array(Om).default([]),publishedAt:e.iso.datetime({offset:!0}).optional(),updatedAt:e.iso.datetime({offset:!0}).optional(),source:e.string(),repositoryUrl:e.string().nullable().default(null),marketplace:e.string(),marketplaceDisplayName:e.string(),publisherKey:e.string(),publisherLabel:e.string(),official:e.boolean(),author:Bo.nullable(),installed:e.boolean(),installedByDefault:e.boolean().default(!1),conflictingInstallSource:e.string().nullable(),installs:e.number().int().nonnegative().nullable().default(null),compatible:e.boolean(),incompatibleReason:e.string().nullable()}),yr=e.object({results:e.array(qm),collections:e.array(Lm),categories:e.array(fi).default([])}),zo=e.discriminatedUnion("kind",[e.object({kind:e.literal("npm"),package:e.string(),range:e.string().optional(),tag:e.string().optional(),registry:e.string().optional(),resolvedVersion:e.string().optional(),resolvedIntegrity:e.string().optional(),unresolvedReason:e.string().optional()}).strict(),e.object({kind:e.literal("git"),url:e.string(),subdir:e.string().optional(),ref:e.string().optional(),range:e.string().optional(),tagPrefix:e.string().optional(),resolvedTag:e.string().optional(),resolvedCommit:e.string().optional(),unresolvedReason:e.string().optional()}).strict()]),Um=e.discriminatedUnion("kind",[e.object({kind:e.literal("bundled"),entryId:e.string(),pluginId:e.string(),displayName:e.string(),source:e.string(),compatible:e.boolean(),incompatibleReason:e.string().nullable()}),e.object({kind:e.literal("marketplace"),entryId:e.string(),pluginId:e.string(),displayName:e.string(),marketplace:e.string(),marketplaceDisplayName:e.string(),official:e.boolean(),author:Bo,source:e.string(),resolvedSource:zo,compatible:e.boolean(),incompatibleReason:e.string().nullable()})]),No=e.object({plan:Um}),Bm=e.enum(["https","git","path"]),vr=e.object({name:e.string(),displayName:e.string(),description:e.string().nullable(),official:e.boolean(),sourceKind:Bm,source:e.string(),subdirectory:e.string().nullable().default(null),resolvedCommit:e.string().nullable(),entryCount:e.number(),lastRefreshAt:e.number().nullable(),lastAttemptAt:e.number().nullable(),lastError:e.string().nullable()}),Ho=e.object({marketplaces:e.array(vr)}),Fo=e.object({source:e.string().min(1),subdirectory:e.string().min(1).optional()}).strict(),Wo=e.object({ok:e.literal(!0),marketplace:vr}),$o=e.object({ok:e.literal(!0),convertedPluginIds:e.array(e.string())}),Qo=e.object({name:Ke.optional()}).strict(),zm=e.object({name:e.string(),ok:e.boolean(),error:e.string().nullable(),marketplace:vr}),Go=e.object({results:e.array(zm)}),Jo=e.object({pluginId:e.string().min(1).optional(),method:e.string().min(1).optional()}),Nm=e.object({pluginId:e.string().min(1),displayName:e.string().min(1),method:e.string().min(1),registrationDescription:e.string().nullable(),methodDescription:e.string().nullable(),inputSchema:e.record(e.string(),S),outputSchema:e.record(e.string(),S)}),Ko=e.array(Nm);var Vo=e.object({providerId:e.string().min(1),cwd:e.string().min(1).optional(),providerOptions:e.record(e.string(),e.unknown()).optional()}).passthrough(),Hm=e.enum(["thread_rewind"]),Rw=Vo.extend({requirement:Hm.optional(),checkUpdates:e.boolean().default(!0)}),Sr=e.object({status:e.enum(["ready","not_installed","unauthenticated","expired","unsupported_version","unknown"]),statusMessage:e.string().min(1).nullable(),accountEmail:e.string().nullable(),planLabel:e.string().min(1).nullable(),installedVersion:e.string().min(1).nullable(),minimumSupportedVersion:e.string().min(1).nullable(),canInstall:e.boolean(),canUpdate:e.boolean(),loginCommand:e.string().min(1).nullable(),localLoginCommand:e.string().min(1).nullable().optional()}).passthrough(),Fm=e.object({label:e.string().min(1),usedPercent:e.number().min(0).max(100),resetsAt:e.string().min(1).nullable(),cost:e.object({usedUsdCents:e.number().int().nonnegative(),limitUsdCents:e.number().int().positive()}).optional()}).passthrough(),Wm=e.discriminatedUnion("status",[e.object({status:e.literal("ok"),accountEmail:e.string().email().nullable(),planLabel:e.string().min(1).nullable(),windows:e.array(Fm)}).passthrough(),e.object({status:e.literal("not_installed")}).passthrough(),e.object({status:e.literal("unauthenticated")}).passthrough(),e.object({status:e.literal("expired")}).passthrough(),e.object({status:e.literal("error"),message:e.string().min(1),planLabel:e.string().min(1).nullable().default(null),accountEmail:e.string().nullable().default(null)}).passthrough()]),Tw=e.discriminatedUnion("supported",[e.object({supported:e.literal(!1)}).passthrough(),e.object({supported:e.literal(!0),health:Sr}).passthrough()]),ww=e.discriminatedUnion("supported",[e.object({supported:e.literal(!1)}).passthrough(),e.object({supported:e.literal(!0),usage:Wm}).passthrough()]),Xo=e.enum(["install","update"]),$m=e.object({kind:Xo,label:e.enum(["Install","Update"]),command:e.string().min(1)}).passthrough(),Qm=e.enum(["notInstalled","npmGlobal","external"]),kw=e.object({executableName:e.string().min(1),executablePath:e.string().min(1).nullable(),installed:e.boolean(),installSource:Qm,currentVersion:e.string().min(1).nullable(),latestVersion:e.string().min(1).nullable(),minimumSupportedVersion:e.string().min(1).nullable(),npmPackageName:e.string().min(1).nullable(),npmGlobalPackageVersion:e.string().min(1).nullable(),installAction:$m.nullable(),needsUpdate:e.boolean(),versionUnsupported:e.boolean()}).passthrough(),Pw=Vo.extend({action:Xo}),Gm=e.object({command:e.string().min(1),args:e.array(e.string()).max(64),displayCommand:e.string().min(1)}).passthrough(),Jm=e.discriminatedUnion("kind",[e.object({kind:e.literal("installed")}).passthrough(),e.object({kind:e.literal("version_changed"),previousVersion:e.string().min(1)}).passthrough(),e.object({kind:e.literal("version_at_least"),version:e.string().min(1)}).passthrough()]),Aw=e.discriminatedUnion("available",[e.object({available:e.literal(!1),message:e.string().min(1)}).passthrough(),e.object({available:e.literal(!0),command:Gm,verification:Jm}).passthrough()]);var Yo=e.string().regex(/^[A-Z_][A-Z0-9_]*$/u).max(128),Ft=e.object({name:Yo,value:e.string().max(65536).refine(n=>!n.includes("\0"),"Environment values cannot contain NUL"),note:e.string().max(1024).nullable().default(null)}).strict(),Zo=e.object({name:Yo,value:e.null(),secret:e.literal(!0),note:e.string().nullable()}).strict(),Km=e.object({builtInGit:e.object({status:e.enum(["logged in","not logged in","overridden","disabled"]),statusMessage:e.string()}),variables:e.array(Zo)}),Cw=Ft.pick({name:!0}),jw=Km.extend({inheritedVariables:e.array(Zo)});var xr=e.object({text:e.string()});var Vm=Ft.extend({value:Ft.shape.value.nullable()}),Nw=e.object({variables:e.array(Vm)}).strict().superRefine(({variables:n},t)=>{let r=new Set;for(let[s,i]of n.entries())r.has(i.name)&&t.addIssue({code:"custom",path:["variables",s,"name"],message:"Machine environment variable names must be unique"}),r.add(i.name)}),Xm=e.enum(["provider_unavailable","missing_executable","auth_required","timeout","failed"]),Ym=e.object({providerId:e.string().min(1),code:Xm,detail:e.string().min(1).nullable()}),Hw=e.object({providers:e.array(Vn),permissionCeiling:L,models:e.array(Kn),selectedOnlyModels:e.array(Kn),modelLoadError:Ym.nullable()}),ea={hostId:e.string().min(1),environmentId:e.string().min(1)},Fw=e.object({...ea,capability:e.enum(["usage"])}).partial().superRefine(V),Ww=e.object({...ea,providerId:e.string().min(1),projectId:e.string().min(1)}).partial().superRefine(V).superRefine((n,t)=>{n.projectId!==void 0&&n.environmentId!==void 0&&t.addIssue({code:"custom",message:"projectId and environmentId are mutually exclusive"})}),$w=e.object({refresh:e.enum(["true","false"]).optional(),hostId:e.string().min(1).optional(),providerId:e.string().min(1).optional()}),Zm=Sr.extend({providerId:e.string().min(1),displayName:e.string().min(1),localLoginCommand:e.string().min(1).nullable()}),Qw=e.object({providers:e.array(Zm)}),eh=e.object({id:e.string().min(1),displayName:e.string().min(1),pluginId:e.string().min(1),tasks:e.array(wn),automaticRank:e.number().int().nonnegative().nullable(),status:Is}),Gw=e.object({selections:As,services:e.array(eh)}),Jw=e.object({task:wn,selection:De}).strict(),Kw=e.object({task:Ps}).strict(),Vw=e.discriminatedUnion("ok",[e.object({ok:e.literal(!0),pluginId:e.string().min(1),serviceId:e.string().min(1),displayName:e.string().min(1),text:e.string(),durationMs:e.number().int().nonnegative()}),e.object({ok:e.literal(!1),message:e.string().min(1),durationMs:e.number().int().nonnegative()})]),ta=e.enum(["agent","projects","plugins","devices"]),Wt=e.enum(["first_run","replay"]),Rr=e.object({step:ta,entry:Wt}).strict(),Xw=e.discriminatedUnion("name",[e.object({name:e.literal("onboarding_agent_state"),properties:e.object({entry:Wt,agent_installed:e.boolean().nullable(),agent_ready:e.boolean().nullable()}).strict()}).strict(),e.object({name:e.literal("onboarding_sign_in"),properties:e.object({entry:Wt,outcome:e.enum(["started","ready","exited","failed","cancelled"])}).strict()}).strict(),e.object({name:e.literal("new_thread_submit"),properties:e.object({outcome:e.enum(["started","accepted","failed"])}).strict()}).strict(),e.object({name:e.literal("onboarding_started"),properties:e.object({agent_installed:e.boolean(),agent_ready:e.boolean()}).strict()}).strict(),e.object({name:e.literal("onboarding_step_reached"),properties:Rr}).strict(),e.object({name:e.literal("onboarding_step_completed"),properties:Rr}).strict(),e.object({name:e.literal("onboarding_step_skipped"),properties:Rr}).strict(),e.object({name:e.literal("onboarding_finished"),properties:e.object({outcome:e.enum(["completed","skipped"]),entry:Wt,last_step:ta}).strict()}).strict()]),th=e.object({providers:e.array(e.object({id:e.string(),displayName:e.string(),description:e.string(),pluginId:e.string().min(1).nullable(),availability:e.discriminatedUnion("status",[e.object({status:e.literal("available"),serverUrl:e.string().url().optional()}),e.object({status:e.literal("setup-required"),message:e.string()}),e.object({status:e.literal("unavailable"),message:e.string()})]).nullable()})),defaultProviderId:e.string(),effectiveUrl:e.string().nullable(),urlSource:e.enum(["setting","BB_EXTERNAL_URL"]).nullable()}),Yw=e.object({serverAccess:th,generalSettings:yt.extend({showUnhandledProviderEvents:e.boolean().optional()}),keybindings:Os,defaultKeybindings:Ls,keybindingOverrides:qs,experiments:Hs,performanceDiagnosticsAvailable:e.boolean(),appearance:Cn,customThemes:e.array(e.string()),pluginThemes:e.array(jn),featureFlags:fs,hostDaemonPort:e.number().nullable(),localHelperPorts:e.array(e.number().int().min(1).max(65535)),serverUrl:e.string().url(),primaryHostId:e.string().nullable(),primaryHostPlatform:pr.nullable(),voiceTranscriptionEnabled:e.boolean(),dataDir:e.string()}),Zw=e.object({hasAttention:e.boolean()}),ek=e.object({dir:e.string(),custom:e.array(e.string()),plugins:e.array(jn),active:Cn}),tk=e.object({currentCommit:e.string().regex(/^[a-f0-9]{40}$/i).nullable(),installKind:e.enum(["desktop","npm","source"]).nullable(),currentVersion:e.string(),latestVersion:e.string().nullable(),source:e.literal("npm"),updateAvailable:e.boolean(),isDevelopment:e.boolean(),upgradeCommand:e.string()}),nk=e.object({force:e.enum(["true","false"]).optional()}),nh=e.object({path:e.string().min(1),source:e.enum(["machine","npm","other"])}),rk=e.object({installedPath:e.string().min(1).nullable(),onPath:e.boolean(),shadowedBy:nh.nullable(),supported:e.boolean()}),Tr=e.object({commit:e.string().nullable(),version:e.string()}),rh=e.discriminatedUnion("kind",[e.object({kind:e.literal("supported"),mode:e.enum(["npm","source"])}),e.object({kind:e.literal("unsupported"),reason:e.enum(["development","desktop","unmanaged"])})]),sh=e.object({channel:e.enum(["latest","nightly","main"]),commit:e.string().nullable(),commitCount:e.number().int().nonnegative().nullable(),subjects:e.array(e.string()),version:e.string()}),ih=e.object({message:e.string(),reason:e.enum(["detached-head","not-on-main","uncommitted-changes","diverged","fetch-failed"])}),oh=e.discriminatedUnion("phase",[e.object({phase:e.literal("idle")}),e.object({output:e.array(e.string()),phase:e.literal("preparing"),startedAt:e.string(),step:e.string(),targetVersion:e.string()}),e.object({phase:e.literal("restarting"),startedAt:e.string(),targetCommit:e.string().nullable(),targetVersion:e.string()})]),ah=e.object({acknowledged:e.boolean(),finishedAt:e.string(),from:Tr,id:e.string(),logTail:e.array(e.string()),message:e.string().nullable(),outcome:e.enum(["updated","failed"]),phase:e.enum(["prepare","install","startup"]).nullable(),to:Tr}),sk=e.object({desktopUpdateSupported:e.literal(!0).optional(),activity:oh,available:sh.nullable(),blocked:ih.nullable(),current:Tr,lastResult:ah.nullable(),runningThreadCount:e.number().int().nonnegative(),support:rh}),ik=e.object({force:e.enum(["true","false"]).optional()}),ok=e.object({confirmInterruptingThreads:e.boolean()}),ak=e.object({id:e.string().min(1)}),lk=e.object({ok:e.literal(!0)}),lh=e.enum(["installed","outdated","missing","unknown"]),dk=e.object({hostIds:e.string().optional()}),ck=e.object({machines:e.array(e.object({hostId:e.string(),hostName:e.string(),status:lh}))}),pk=e.object({hostIds:e.array(e.string().min(1)).min(1).max(64)}),uk=e.object({results:e.array(e.discriminatedUnion("ok",[e.object({ok:e.literal(!0),hostId:e.string(),hostName:e.string(),installations:e.array(e.object({name:e.string(),path:e.string()}))}),e.object({ok:e.literal(!1),hostId:e.string(),hostName:e.string(),errorMessage:e.string()})]))}),mk=e.object({projectId:e.string().min(1).optional(),hostId:e.string().min(1).optional()}).superRefine((n,t)=>{n.hostId!==void 0&&n.projectId===void 0&&t.addIssue({code:"custom",path:["hostId"],message:"hostId requires projectId"})}),dh=e.object({id:e.string().min(1),displayName:e.string().min(1),description:e.string().min(1),icon:e.string().min(1),logoUrl:e.string().min(1).nullable(),pluginId:e.string().min(1),inputs:S.nullable(),acceptsEmptyInputs:e.boolean(),supportsSuspend:e.boolean()}),hk=e.object({providers:e.array(dh)}),gk=e.object({version:e.string().min(1),versionCode:e.number().int().positive(),size:e.number().int().positive(),sha256:e.string().regex(/^[a-f0-9]{64}$/)}),fk=e.object({id:e.string(),displayName:e.string(),pluginId:e.string(),pluginName:e.string(),pluginEnabled:e.boolean(),enabled:e.boolean(),available:e.boolean(),logoUrl:e.string().nullable(),info:Vn.nullable()}),bk=e.object({enabled:e.boolean()}).strict();var ch=["pending","completed","error","interrupted"],$t=e.enum(ch),ph=["waiting_for_approval","denied"],wr=e.enum(ph).nullable(),uh=e.discriminatedUnion("type",[e.object({type:e.literal("read"),command:e.string(),name:e.string(),path:e.string().nullable()}),e.object({type:e.literal("list_files"),command:e.string(),path:e.string().nullable()}),e.object({type:e.literal("search"),command:e.string(),query:e.string().nullable(),path:e.string().nullable()}),e.object({type:e.literal("unknown"),command:e.string()})]),Qt=e.object({id:e.string(),threadId:e.string(),turnId:e.string().nullable(),sourceSeqStart:e.number().int(),sourceSeqEnd:e.number().int(),startedAt:e.number(),createdAt:e.number()}),mh=e.object({webImages:e.number().int().nonnegative(),localImages:e.number().int().nonnegative(),localFiles:e.number().int().nonnegative(),imageUrls:e.array(e.string()),localImagePaths:e.array(e.string()),localFilePaths:e.array(e.string()),localFileDetails:e.array(e.object({path:e.string(),name:e.string(),sizeBytes:e.number().int().nonnegative().nullable()}))}),hh=["message","steer"],gh=["pending","accepted","rejected"],fh=e.object({isGrouped:e.boolean(),kind:e.enum(hh),status:e.enum(gh)}),na=Qt.extend({kind:e.literal("conversation"),messageSeq:e.number().int(),text:e.string(),attachments:mh.nullable()}),bh=na.extend({role:e.literal("user"),initiator:Ss,senderThreadId:e.string().nullable(),systemMessageKind:mt,systemMessageSubject:ht.nullable(),turnRequest:fh,mentions:e.array(ls)}),yh=e.object({kind:e.literal("hook"),hookEvent:e.string().min(1),reason:e.string().nullable()}),vh=na.extend({role:e.literal("assistant"),turnRequest:e.null(),rejection:yh.nullable()}),Ve=e.discriminatedUnion("role",[bh,vh]),Sh=["generic","reasoning","compaction","context-clear","parent-change","thread-provisioning","thread-interrupted","provider-unhandled","warning","deprecation"],xh=e.enum(Sh),Rh=xh.exclude(["parent-change"]),Th=["assign","release","transfer"],wh=e.enum(Th),kh=e.object({action:wh,previousParentThreadId:e.string().nullable(),previousParentThreadTitle:e.string().nullable(),nextParentThreadId:e.string().nullable(),nextParentThreadTitle:e.string().nullable()}),Gt={contentDeferred:e.literal(!0).optional()},kr=Qt.extend({kind:e.literal("system"),title:e.string(),detail:e.string().nullable(),status:$t.nullable()}),Ph=kr.extend({systemKind:e.enum(["debug","error","reconnect"])}),Ah=kr.extend({systemKind:e.literal("operation"),operationKind:Rh,reasoningId:e.string().optional(),completedAt:e.number().nullable(),...Gt}),Ih=kr.extend({systemKind:e.literal("operation"),operationKind:e.literal("parent-change"),status:$t,parentChange:kh,completedAt:e.number().nullable()}),Eh=e.discriminatedUnion("operationKind",[Ah,Ih]),Ch=e.union([Ph,Eh]),jh=e.object({added:e.number().int().nonnegative(),removed:e.number().int().nonnegative()}),_h=e.object({path:e.string(),kind:e.string().nullable(),movePath:e.string().nullable(),diff:e.string().nullable(),diffStats:jh}),w=Qt.extend({kind:e.literal("work"),status:$t}),Pr=gt,I={presentation:Pr.optional()},ra=e.object({experimental_fullOutputAvailability:e.enum(["available","detail-limit","retention-expired"]),totalChars:e.number().int().nonnegative()}),Mh=w.extend({workKind:e.literal("command"),callId:e.string(),command:e.string(),cwd:e.string().nullable(),source:e.string().nullable(),output:e.string(),outputPreview:ra.optional(),exitCode:e.number().nullable(),completedAt:e.number().nullable(),approvalStatus:wr,activityIntents:e.array(uh),...I,...Gt}),Dh=w.extend({workKind:e.literal("tool"),callId:e.string(),toolName:e.string(),toolArgs:e.record(e.string(),S).nullable(),output:e.string(),outputPreview:ra.optional(),completedAt:e.number().nullable(),approvalStatus:wr,...I,...Gt}),Oh=w.extend({workKind:e.literal("file-change"),callId:e.string(),change:_h,stdout:e.string().nullable(),stderr:e.string().nullable(),approvalStatus:wr,...I,...Gt}),Lh=w.extend({workKind:e.literal("web-search"),callId:e.string(),queries:e.array(e.string()),completedAt:e.number().nullable(),...I}),qh=w.extend({workKind:e.literal("web-fetch"),callId:e.string(),url:e.string(),prompt:e.string().nullable(),pattern:e.string().nullable(),completedAt:e.number().nullable(),...I}),Uh=w.extend({workKind:e.literal("image-view"),callId:e.string(),path:e.string(),completedAt:e.number().nullable(),...I}),Bh=w.extend({workKind:e.literal("image-generation"),callId:e.string(),prompt:e.string().nullable(),path:e.string().nullable(),error:e.string().nullable(),transparentBackground:e.boolean(),completedAt:e.number().nullable(),...I}),zh=w.extend({workKind:e.literal("file-read"),callId:e.string(),path:e.string(),cmd:e.string().nullable(),completedAt:e.number().nullable(),...I}),Nh=w.extend({workKind:e.literal("search"),callId:e.string(),mode:ws,query:e.string(),path:e.string().nullable(),cmd:e.string().nullable(),completedAt:e.number().nullable(),...I}),Hh=w.extend({workKind:e.literal("plan-steps"),callId:e.string(),steps:e.array(Ts),explanation:e.string().nullable(),completedAt:e.number().nullable(),...I}),Fh=w.extend({workKind:e.literal("extension"),callId:e.string(),extensionKind:ft,payload:S,completedAt:e.number().nullable(),presentation:Pr}),Wh=["waiting","denied"],$h=["pending","resolving","granted","denied","interrupted"],Qh=["pending","resolving","answered","interrupted"],Gh=["turn","session"],Jh=e.enum(Gh),Kh=e.object({itemId:e.string(),toolName:e.string().nullable()}),sa=w.extend({workKind:e.literal("approval"),interactionId:e.string(),target:Kh}),Vh=sa.extend({approvalKind:e.literal("file-edit"),lifecycle:e.enum(Wh)}),Xh=sa.extend({approvalKind:e.literal("permission-grant"),lifecycle:e.enum($h),grantScope:Jh.nullable(),statusReason:e.string().nullable()}),Yh=e.discriminatedUnion("approvalKind",[Vh,Xh]),Zh=["pending","submitted","cancelled"],eg=w.extend({workKind:e.literal("form"),interactionId:e.string(),pluginId:e.string(),rendererId:e.string(),title:e.string(),lifecycle:e.enum(Zh),statusReason:e.string().nullable(),presentation:Pr,payload:S.nullable()}),tg=w.extend({workKind:e.literal("question"),interactionId:e.string(),lifecycle:e.enum(Qh),questions:e.array(bs),answers:e.record(e.string(),ys).nullable(),statusReason:e.string().nullable()}),ng=w.extend({workKind:e.literal("delegation"),callId:e.string(),toolName:e.string(),childRef:e.string().nullable(),background:e.boolean(),subagentType:e.string().nullable(),description:e.string().nullable(),output:e.string(),completedAt:e.number().nullable(),childRows:e.array(e.lazy(()=>ee)).nullable(),...I}),Jt=w.extend({workKind:e.literal("workflow"),itemId:e.string(),taskType:e.string(),workflowName:e.string().nullable(),description:e.string(),model:e.string().nullable(),taskStatus:us,workflow:ms.nullable(),usage:hs.nullable(),summary:e.string().nullable(),error:e.string().nullable(),completedAt:e.number().nullable(),...I}),rg=e.union([Mh,Dh,Oh,Lh,qh,Bh,Uh,zh,Nh,Hh,Fh,Yh,tg,eg,ng,Jt]),sg=e.lazy(()=>Qt.extend({kind:e.literal("turn"),turnId:e.string().min(1),status:$t,summaryCount:e.number().int().nonnegative(),completedAt:e.number().nullable(),children:e.array(ee).nullable()})),ee=e.lazy(()=>e.union([Ve,rg,Ch,sg])),ia=e.object({upsertRows:e.array(ee),rowOrder:e.array(e.string()).optional()});var Xe="Retry";function Ar(n){return n===""?[]:n.split(",")}var ig="none",Kt=20;var Vt=e.enum(["workspace","thread-storage"]),Ye=e.enum(["right","down","left","top","replace"]),og=e.object({source:Vt,path:e.string().min(1),lineNumber:e.number().int().positive().nullable()}),ag=e.object({type:e.literal("thread-open"),projectId:e.string(),threadId:e.string(),split:Ye,file:og.nullable()}),Ze=e.enum(["maximize","restore","toggle","spotlight","clear-spotlight"]),lg=e.object({type:e.literal("thread-pane-action"),projectId:e.string(),threadId:e.string(),action:Ze}),dg=e.object({type:e.literal("thread-timeline"),target:He,afterSequence:e.number().int().nonnegative().nullable(),timeline:e.custom(n=>typeof n=="object"&&n!==null)});var pg=e.enum(["queue-if-active","steer-if-active","auto","start","steer"]),N=ds,ug=e.object({providerId:N.optional(),model:N.optional(),serviceTier:N.optional(),reasoningLevel:N.optional(),permissionMode:N.optional()}).strict(),ma=e.object({model:N.optional(),serviceTier:N.optional(),reasoningLevel:N.optional(),permissionMode:N.optional()}).strict(),Ok=e.object({projectId:e.string().min(1),providerId:e.string().min(1).optional(),origin:qe,originPluginId:e.string().min(1).optional(),pluginMetadata:fe.optional(),lifecycleOwnerThreadId:e.string().min(1).optional(),visibility:ge.optional(),title:e.string().min(1).optional(),input:e.array(_),model:e.string().min(1).optional(),serviceTier:K.optional(),reasoningLevel:O.optional(),sessionOptions:pt.optional(),permissionMode:_e.optional(),executionInputSources:ug.optional(),environment:ir,parentThreadId:e.string().min(1).optional(),senderThreadId:e.string().min(1).optional(),parentNotifications:Ue.optional(),sectionId:e.string().min(1).nullable().optional(),pinned:e.boolean().optional(),sourceThreadId:e.string().min(1).optional(),sourceSeqEnd:e.number().int().nonnegative().optional(),startedOnBehalfOf:ji.nullable().default(null),originKind:he.nullable().default(null),sendAt:e.number().int().nonnegative().optional(),pluginSubmission:e.object({pluginId:k,data:S}).optional()}).superRefine((n,t)=>{n.origin==="plugin"&&n.originPluginId===void 0&&t.addIssue({code:"custom",message:'originPluginId is required when origin is "plugin"',path:["originPluginId"]}),n.origin!=="plugin"&&n.originPluginId!==void 0&&t.addIssue({code:"custom",message:'originPluginId requires origin "plugin"',path:["originPluginId"]}),n.pluginMetadata!==void 0&&n.origin!=="plugin"&&t.addIssue({code:"custom",message:'pluginMetadata requires origin "plugin"',path:["pluginMetadata"]}),n.pluginMetadata!==void 0&&n.originPluginId!==void 0&&!k.safeParse(n.originPluginId).success&&t.addIssue({code:"custom",message:"pluginMetadata requires originPluginId to be a valid plugin id",path:["originPluginId"]}),n.originKind===null&&n.input.length===0&&t.addIssue({code:"custom",message:"input must contain at least one entry",path:["input"]}),n.originKind===null&&n.sourceSeqEnd!==void 0&&t.addIssue({code:"custom",message:"sourceSeqEnd requires an originKind",path:["sourceSeqEnd"]})}),mg=_.and(e.object({visibility:e.literal("agent-only")})),Lk=e.object({sourceThreadId:e.string().min(1),sourceSeqEnd:e.number().int().nonnegative().optional(),input:e.array(_).min(1).optional(),agentContextSeed:e.array(mg).min(1).optional(),title:e.string().min(1).optional(),permissionMode:_e.optional(),visibility:ge.default("visible"),environment:ir.optional(),origin:qe.default("sdk"),originPluginId:e.string().min(1).optional(),pluginMetadata:fe.optional(),lifecycleOwnerThreadId:e.string().min(1).optional()}).strict().superRefine((n,t)=>{n.origin==="plugin"&&n.originPluginId===void 0&&t.addIssue({code:"custom",message:'originPluginId is required when origin is "plugin"',path:["originPluginId"]}),n.origin!=="plugin"&&n.originPluginId!==void 0&&t.addIssue({code:"custom",message:'originPluginId requires origin "plugin"',path:["originPluginId"]}),n.pluginMetadata!==void 0&&n.origin!=="plugin"&&t.addIssue({code:"custom",message:'pluginMetadata requires origin "plugin"',path:["pluginMetadata"]}),n.pluginMetadata!==void 0&&n.originPluginId!==void 0&&!k.safeParse(n.originPluginId).success&&t.addIssue({code:"custom",message:"pluginMetadata requires originPluginId to be a valid plugin id",path:["originPluginId"]})}),hg=e.object({input:e.array(_).min(1),model:e.string().optional(),serviceTier:K.optional(),reasoningLevel:O.optional(),permissionMode:_e.optional(),executionInputSources:ma.optional(),mode:pg,senderThreadId:e.string().min(1).optional(),originPluginId:k.optional(),pluginSubmission:e.object({pluginId:k,data:S}).optional(),sendAt:e.number().int().nonnegative().optional(),compactFirst:e.literal(!0).optional()});var qk=e.enum(["sent","queued"]),Uk=e.discriminatedUnion("delivery",[e.object({ok:e.literal(!0),delivery:e.literal("sent")}),e.object({ok:e.literal(!0),delivery:e.literal("queued"),queuedMessage:qn})]),Bk=hg.omit({mode:!0,sendAt:!0,pluginSubmission:!0,compactFirst:!0}).extend({operationId:e.string().min(1),expectedRequestSequence:e.number().int().nonnegative().optional()}).strict(),zk=e.object({ok:e.literal(!0),operationId:e.string().min(1),requestSequence:e.number().int().nonnegative()}).strict(),Nk=e.object({turnRequestId:pe.nullable().default(null),sendAt:e.number().int().nonnegative().nullable().default(null),reason:Rt.default(Xe)}).strict(),Hk=e.discriminatedUnion("delivery",[e.object({ok:e.literal(!0),delivery:e.literal("sent"),turnRequestId:pe,attempt:e.number().int().min(2)}),e.object({ok:e.literal(!0),delivery:e.literal("queued"),turnRequestId:pe,attempt:e.number().int().min(2),queuedMessageId:e.string().min(1),waitingOn:Tt,sendAt:e.number().int().nonnegative().nullable()})]),gg=e.enum(["auto","steer"]),Fk=e.object({input:e.array(_).min(1),model:e.string().optional(),serviceTier:K.optional(),reasoningLevel:O.optional(),permissionMode:_e.optional(),executionInputSources:ma.optional(),senderThreadId:e.string().min(1).optional()}),Wk=e.object({expectedUpdatedAt:e.number().int().nonnegative(),input:e.array(_).min(1)}),$k=e.object({leaseMs:e.number().int().positive()}),Qk=e.object({mode:gg}),Gk=e.object({previousQueuedMessageId:e.string().min(1).nullable(),nextQueuedMessageId:e.string().min(1).nullable(),groupBoundaryQueuedMessageId:e.string().min(1).optional()}),Jk=e.object({expectedGroupedPrefixQueuedMessageIds:e.array(e.string().min(1)).min(1),groupBoundaryQueuedMessageId:e.string().min(1)});var Kk=e.array(Ne),Vk=e.object({threadIds:e.array(Zn).max(32)}).strict(),fg=e.object({threadId:Zn,projectId:e.string().min(1),label:e.string().min(1)}).strict(),Xk=e.array(fg),bg=e.object({start:e.number().int().nonnegative(),end:e.number().int().positive()}).strict().refine(n=>n.end>n.start,{message:"highlight range end must be greater than start"}),yg=e.object({sourceKind:_i,text:e.string(),highlightRanges:e.array(bg),sourceSeq:e.number().int().nonnegative().nullable()}).strict(),vg=e.object({thread:Ne,matches:e.array(yg)}).strict(),oa=e.object({total:e.number().int().nonnegative(),results:e.array(vg)}).strict(),Yk=e.object({active:oa,archived:oa}).strict(),Sg=Un.extend({activeBackgroundAgentCount:e.number().int().nonnegative(),canRestoreEnvironment:e.boolean(),canEditMessages:e.boolean(),canSpawnChild:e.boolean(),queuedMessageCount:e.number().int().nonnegative()}),xg=e.enum(["environment","host"]),Zk=e.object({include:e.string().min(1).refine(n=>Qe({allowedValues:xg.options,value:n}),{message:"Invalid include"}).optional()}),eP=e.object({pluginId:k}).strict(),tP=e.object({pluginId:k,threadIds:e.array(e.string().min(1)).min(1).max(200)}).strict(),nP=e.object({threads:e.array(e.object({threadId:e.string(),metadata:fe}).strict())}).strict(),rP=e.object({threadIds:e.array(e.string().min(1)).min(1).max(200)}).strict(),sP=e.object({threads:e.array(e.object({threadId:e.string(),ancestorIds:e.array(e.string())}).strict())}).strict(),iP=e.object({threadIds:e.array(e.string().min(1)).min(1).max(200),includeArchived:e.boolean().optional(),includeHidden:e.boolean().optional()}).strict(),oP=e.object({threads:e.array(e.object({threadId:e.string(),descendantIds:e.array(e.string())}).strict())}).strict(),aP=e.object({pluginId:k,set:fe.optional(),remove:e.array(e.string()).optional()}).strict().superRefine(({set:n,remove:t},r)=>{t&&new Set(t).size!==t.length&&r.addIssue({code:"custom",message:"remove contains duplicate keys",path:["remove"]}),n&&t?.some(s=>Object.hasOwn(n,s))&&r.addIssue({code:"custom",message:"set and remove overlap",path:["remove"]})}),lP=Sg.extend({environment:St.nullable().optional(),host:hi.nullable().optional(),environmentHostName:e.string().nullable().optional()}),dP=e.array(vs);var cP=e.object({value:S}),pP=e.object({threadId:e.string().min(1).optional(),waitHolder:Xs.optional()}),uP=e.array(qn),mP=e.object({nonDeletedChildCount:e.number().int().nonnegative(),unarchivedDescendantCount:e.number().int().nonnegative()}),hP=e.object({childThreadsConfirmed:e.boolean()}),gP=e.object({title:e.string().min(1).nullable(),sectionId:e.string().min(1).nullable(),parentThreadId:e.string().min(1).nullable(),model:e.string().min(1).nullable(),reasoningLevel:O.nullable(),sessionOptions:e.record(e.string().min(1),cs.nullable()),visibility:ge,parentNotifications:Ue}).partial().refine(n=>n.parentNotifications!==void 0||n.title!==void 0||n.sectionId!==void 0||n.parentThreadId!==void 0||n.model!==void 0||n.reasoningLevel!==void 0||n.sessionOptions!==void 0||n.visibility!==void 0,"At least one field must be provided"),fP=e.object({previousThreadId:e.string().min(1).nullable(),nextThreadId:e.string().min(1).nullable()}),ha=e.object({source:Vt,path:e.string().min(1),lineNumber:e.number().int().positive().nullable()}).strict(),bP=e.object({type:e.literal("thread-open"),projectId:e.string().min(1),threadId:e.string().min(1),split:Ye,file:ha.nullable()}).strict(),yP=e.object({split:Ye.optional(),file:ha.nullable()}).strict(),vP=e.object({delivered:e.number().int().nonnegative()}),SP=e.object({action:Ze}).strict(),xP=e.object({type:e.literal("thread-pane-action"),projectId:e.string().min(1),threadId:e.string().min(1),action:Ze}).strict(),RP=e.object({delivered:e.number().int().nonnegative()}),TP=e.object({ok:e.literal(!0),archivedThreadIds:e.array(e.string().min(1))}),wP=e.object({projectId:e.string().min(1).optional(),environmentId:e.string().min(1).optional(),hostId:e.string().min(1).optional(),parentThreadId:e.string().min(1).optional(),sourceThreadId:e.string().min(1).optional(),archived:e.enum(["true","false"]).optional(),sectionId:e.string().min(1).optional(),unsectioned:e.enum(["true","false"]).optional(),hasParent:e.enum(["true","false"]).optional(),originKind:he.optional(),originPluginId:e.string().min(1).optional(),includeHidden:e.enum(["true","false"]).optional(),threadIds:e.string().refine(n=>{let t=Ar(n);return t.length<=200&&t.every(r=>r.length>0)},{message:`threadIds must be at most ${200} comma-separated thread IDs`}).optional(),limit:e.string().regex(/^\d+$/).optional(),offset:e.string().regex(/^\d+$/).optional()}),Rg=e.enum(["host","provider","project"]),kP=e.object({status:B.optional(),hostId:e.string().min(1).optional(),providerId:e.string().min(1).optional(),projectId:e.string().min(1).optional(),parentThreadId:e.string().min(1).optional(),groupBy:Rg.optional(),includeArchived:e.enum(["true","false"]).optional(),includeHidden:e.enum(["true","false"]).optional()}),PP=e.object({total:e.number().int().nonnegative(),groups:e.array(e.object({key:e.string().nullable(),count:e.number().int().nonnegative()})).optional()}),Tg=e.object({id:e.string(),hostId:e.string().nullable()}),AP=e.array(Tg),IP=e.object({query:e.string().trim().min(2),limitPerGroup:e.string().regex(/^\d+$/).optional()}),wg=e.object({anchorSeq:e.number().int().nonnegative(),anchorId:e.string().min(1)}).strict(),kg=e.object({returnedSegmentCount:e.number().int().nonnegative(),olderCursor:wg.nullable(),historySnapshot:e.string(),olderRowsSourceSeqEnd:e.number().int().nonnegative().nullable(),olderRowUpdates:e.array(ee).optional()}).strict(),EP=e.object({includeNestedRows:e.enum(["true","false"]),segmentLimit:e.string().regex(/^\d+$/),beforeAnchorSeq:e.string().regex(/^(0|[1-9]\d*)$/),beforeAnchorId:e.string().min(1),summaryOnly:e.enum(["true","false"]),afterSequence:e.string().regex(/^\d+$/),deferContent:e.enum(["true","false"])}).partial().superRefine((n,t)=>{let r=n.beforeAnchorSeq!==void 0,s=n.beforeAnchorId!==void 0;r!==s&&t.addIssue({code:"custom",message:"beforeAnchorSeq and beforeAnchorId must be provided together",path:r?["beforeAnchorId"]:["beforeAnchorSeq"]})}),CP=e.object({beforeCursor:e.string().min(1).optional(),deferContent:e.enum(["true","false"]).optional(),itemId:e.string().min(1).optional(),turnId:e.string().min(1),sourceSeqStart:e.string().regex(/^\d+$/),sourceSeqEnd:e.string().regex(/^\d+$/)}),jP=e.object({afterSeq:e.string().regex(/^\d+$/),beforeSeq:e.string().regex(/^\d+$/),limit:e.string().regex(/^\d+$/).refine(n=>Number(n)<=100,`Thread event limit cannot exceed ${100}`),order:e.enum(["asc","desc"]),types:e.string().refine(n=>Qe({allowedValues:ut,value:n}),"Invalid thread event types")}).partial(),_P=e.object({type:e.string().min(1),afterSeq:e.string().regex(/^\d+$/).optional(),waitMs:e.string().regex(/^\d+$/).optional()}),aa=e.string().regex(/^\d+$/).refine(n=>Number(n)<=Kt,`Message context cannot exceed ${Kt}`),MP=e.object({before:aa,after:aa}).partial(),DP=e.object({message:Ve,before:e.array(Ve),after:e.array(Ve)}),Pg=e.object({query:e.string().min(1).max(256),limit:e.string().regex(/^\d+$/)}).partial(),OP=Pg.extend({includeFiles:z,includeDirectories:z}),LP=e.object({hostId:e.string().min(1),storageRootPath:e.string().min(1)}).strict(),qP=e.object({olderCursor:e.string().nullable().optional(),historySnapshot:e.string().optional(),rows:e.array(ee)}),la={id:e.string().min(1),label:e.string().min(1),description:e.string().nullable(),category:e.string().nullable()},Ag=e.discriminatedUnion("type",[e.object({...la,type:e.literal("select"),value:e.string(),pendingValue:e.string().nullable(),values:e.array(e.object({id:e.string().min(1),label:e.string().min(1),description:e.string().nullable(),group:e.string().nullable()}))}),e.object({...la,type:e.literal("boolean"),value:e.boolean(),pendingValue:e.boolean().nullable()})]),Ig=e.object({rows:e.array(ee),contextBoundarySeq:e.number().int().nonnegative().nullable(),completedTurnDisplay:ue,activePromptMode:Mi.nullable(),activeThinking:Ks.nullable(),activeWorkflows:e.array(Jt),activeBackgroundCommands:e.array(Jt),pendingTodos:Oi.nullable(),goal:xs.nullable(),providerCommands:e.array(lr.omit({pluginId:!0})).nullable(),sessionOptions:e.array(Ag).nullable(),modelFallback:Di.nullable(),contextWindowUsage:rr.optional(),timelinePage:kg,maxSeq:e.number().int().nonnegative(),delta:ia.optional()}),UP=e.object({type:e.literal("thread-timeline"),target:He,afterSequence:e.number().int().nonnegative().nullable(),timeline:Ig}).strict(),Eg=e.object({imageCount:e.number().int().nonnegative(),fileCount:e.number().int().nonnegative()}).strict(),Cg=e.object({id:e.string().min(1),role:e.enum(["user","assistant"]),preview:e.string(),attachmentSummary:Eg.nullable()}).strict(),BP=e.object({role:e.enum(["user","assistant"])}).partial(),zP=e.object({items:e.array(Cg),maxSeq:e.number().int().nonnegative()}).strict(),NP=Gi.extend({storageRootPath:e.string()}),HP=Ji.extend({storageRootPath:e.string()});var jg=4194304,te=32768,Xt=1024,_g=4096,Mg=1048576,Dg=2097152,Og=200,Lg=8388608,E=e.string().min(1).max(jg),ne=e.string().min(1).max(te),Se=e.object({endLineNumber:e.number().int().positive(),startLineNumber:e.number().int().positive()}).strict().refine(n=>n.startLineNumber<=n.endLineNumber),ga=e.discriminatedUnion("kind",[e.object({kind:e.literal("working-tree")}).strict(),e.object({kind:e.literal("head")}).strict(),e.object({kind:e.literal("merge-base"),ref:e.string().min(1).max(te)}).strict()]),qg=e.discriminatedUnion("kind",[e.object({environmentId:e.string().min(1).nullable(),kind:e.literal("workspace-file-preview"),projectId:e.string().min(1).nullable(),tab:e.object({lineRange:Se.nullable(),path:ne,source:ga,statusLabel:e.literal("deleted").nullable()}).strict(),threadId:e.string().min(1).nullable()}).strict(),e.object({environmentId:e.string().min(1).nullable().default(null),hostId:e.string().min(1).nullable().default(null),kind:e.literal("host-file-preview"),tab:e.object({lineRange:Se.nullable(),path:ne}).strict(),threadId:e.string().min(1).nullable().default(null)}).strict().refine(n=>n.hostId!==null||n.environmentId!==null&&n.threadId!==null,{message:"hostId or threadId/environmentId is required"}),e.object({environmentId:e.string().min(1).nullable(),kind:e.literal("thread-storage-file-preview"),tab:e.object({lineRange:Se.nullable(),path:ne}).strict(),threadId:e.string().min(1)}).strict()]),Ug=e.discriminatedUnion("kind",[e.object({id:E,kind:e.literal("thread-info")}).strict(),e.object({id:E,kind:e.literal("git-diff")}).strict(),e.object({id:E,kind:e.literal("plugin-fixed"),pluginId:e.string().min(1).max(te),tabId:e.string().min(1).max(te)}).strict(),e.object({actionId:e.string().min(1).max(te),fileOpenerOwner:qg.optional(),id:E,kind:e.literal("plugin-panel"),paramsJson:e.string().max(Mg).nullable(),pluginId:e.string().min(1).max(te),title:e.string().min(1).max(Xt)}).strict(),e.object({environmentId:e.string().min(1).nullable(),id:E,kind:e.literal("workspace-file-preview"),lineRange:Se.nullable(),path:ne,projectId:e.string().min(1).nullable(),source:ga,statusLabel:e.literal("deleted").nullable()}).strict(),e.object({environmentId:e.string().min(1).nullable(),hostId:e.string().min(1).nullable().default(null),id:E,kind:e.literal("host-file-preview"),lineRange:Se.nullable(),path:ne,threadId:e.string().min(1).nullable()}).strict(),e.object({environmentId:e.string().min(1).nullable(),id:E,isPinned:e.boolean(),kind:e.literal("thread-storage-file-preview"),lineRange:Se.nullable(),path:ne,threadId:e.string().min(1).nullable()}).strict(),e.object({id:E,kind:e.literal("attachment-file-preview"),name:e.string().min(1).max(Xt),path:ne,projectId:e.string().min(1)}).strict(),e.object({environmentId:e.string().min(1).nullable(),id:E,kind:e.literal("browser"),desktopTarget:e.object({hostId:e.string().min(1),instanceId:e.string().min(1),generation:e.string().min(1)}).strict().optional(),title:e.string().min(1).max(Xt).nullable(),url:e.string().max(_g)}).strict(),e.object({id:E,kind:e.literal("new-tab")}).strict(),e.object({id:E,kind:e.literal("side-chat"),sourceMessageText:e.string().max(Dg),sourceSeqEnd:e.number().int().nonnegative().nullable(),threadId:e.string().min(1).nullable(),title:e.string().min(1).max(Xt)}).strict(),e.object({id:E,kind:e.literal("terminal"),target:er.optional(),terminalId:e.string().min(1).max(te)}).strict()]),fa=e.array(Ug).max(Og).superRefine((n,t)=>{JSON.stringify(n).length>Lg&&t.addIssue({code:"custom",message:"Thread tabs payload is too large"});let r=new Set;for(let[s,i]of n.entries())r.has(i.id)&&t.addIssue({code:"custom",message:`Duplicate tab id: ${i.id}`,path:[s,"id"]}),r.add(i.id)}),Er=e.object({revision:e.number().int().nonnegative(),tabs:fa}).strict(),JP=e.object({expectedRevision:e.number().int().nonnegative(),tabs:fa}).strict();var et=Z.extend({screenshots:Z.shape.screenshots.default([]),collections:Z.shape.collections.default([]),providerIds:e.array(e.string()).default([]),icons:e.record(e.string(),e.string()).default({})}),Bg=e.object({plugins:e.array(et)}),Cr=e.object({ok:e.literal(!0),plugin:et}),zg=e.union([Ao,Cr]),ba=500,Ng=e.object({ok:e.literal(!0),plugins:e.array(et)}),Hg=yr.extend({collections:yr.shape.collections.default([])}),Fg=e.object({ok:e.boolean(),error:e.string().optional(),plugin:et.optional(),plugins:e.array(et).optional()});function Wg(n){if(n.subdirectory!==void 0)return{kind:"subdirectory",path:n.subdirectory};if(n.plugin!==void 0)return{kind:"entry",name:n.plugin}}function H(n,t=""){let r=e.string().min(1).parse(n);return`/api/v1/plugins/${encodeURIComponent(r)}${t}`}function ya(n){let{transport:t}=n;async function r(d,u,f){let v=t.baseUrl?`${t.baseUrl.replace(/\/$/u,"")}${d}`:d,ct=await(await t.resolve(t.fetch(v,f))).json();return u.parse(ct)}function s(d,u){return{method:d,headers:{"content-type":"application/json"},body:JSON.stringify(u)}}function i(d,u=""){let f=e.string().min(1).parse(d);return`/api/v1/plugins/install-jobs/${encodeURIComponent(f)}${u}`}let a={async get(d){let u=e.string().min(1).parse(d.jobId);return(await r(`/api/v1/plugins/update-jobs/${encodeURIComponent(u)}`,hr)).job},async list(d={}){return(await r("/api/v1/plugins/update-jobs",To,{signal:d.signal})).jobs}};function l(d){return r(H(d.pluginId,"/update"),e.union([hr,mr]),{method:"POST",headers:{"content-type":"application/json",prefer:"respond-async"},body:JSON.stringify(xo.parse({}))})}let p={async cancel(d){return(await r(i(d.jobId,"/cancel"),fr,s("POST",{}))).job},async get(d){return(await r(i(d.jobId),fr)).job},async list(d={}){return(await r("/api/v1/plugins/install-jobs",Io,{signal:d.signal})).jobs}};function m(d,u){return r(d,zg,{method:"POST",headers:{"content-type":"application/json",prefer:"respond-async"},body:JSON.stringify(u)})}async function o(d,u){let f=await m(d,u);if("job"in f)return f.job;throw new Error(`installed "${f.plugin.id}" without an install job; this BB server predates background installs`)}async function g(d,u){let f=await m(d,u);if("plugin"in f)return f.plugin;let v=f.job;for(;v.state==="queued"||v.state==="running"||v.state==="cancelling";)await new Promise(G=>setTimeout(G,ba)),v=await p.get({jobId:v.id});if(v.state==="succeeded")return v.plugin;throw new Error(v.state==="failed"?v.error:"install cancelled")}function h(d){if(d.subdirectory!==void 0&&d.plugin!==void 0)throw new Error("plugin install accepts subdirectory or plugin, not both");let u=Wg(d),f=u===void 0?{source:d.source}:{source:d.source,selection:u};return Po.parse(f),f}return{async applyUpdate(d){let u=await l(d);if(!("job"in u))return u;let f=u.job;for(;f.state==="queued"||f.state==="running";)await new Promise(v=>setTimeout(v,ba)),f=await a.get({jobId:f.id});if(f.state==="completed")return f.result;throw new Error(f.error)},async experimental_startUpdate(d){let u=await l(d);if("job"in u)return u.job;throw new Error("Update completed without a job; this BB server predates background updates")},experimental_updateJobs:a,async experimental_discoverRpc(d={}){let u=Jo.parse(d),f=new URLSearchParams;return u.pluginId!==void 0&&f.set("pluginId",u.pluginId),u.method!==void 0&&f.set("method",u.method),r(`/api/v1/plugins/rpc?${f}`,Ko,{signal:d.signal})},async callRpc(d){let u=await r(H(d.pluginId,`/rpc/${encodeURIComponent(d.method)}`),e.object({ok:e.literal(!0),result:S}),{...s("POST",d.input??null),signal:d.signal});return d.outputSchema.parse(u.result)},async checkUpdates(d={}){let u=So.parse(d.pluginId===void 0?{}:{id:d.pluginId});return(await r("/api/v1/plugins/updates/check",ur,{...s("POST",u),signal:d.signal})).results},async experimental_getSafeMode(d={}){return r("/api/v1/plugins/safe-mode",_o,{signal:d.signal})},async experimental_setSafeMode(d){let u=jo.parse({enabled:d.enabled});return r("/api/v1/plugins/safe-mode",Mo,s("PUT",u))},async experimental_pruneCache(d={}){let u=Do.parse({dryRun:d.dryRun??!1});return r("/api/v1/plugins/cache/prune",Oo,{...s("POST",u),signal:d.signal})},catalog:{async install(d){return g("/api/v1/plugin-catalog/install",Ht.parse(d))},async startInstall(d){return o("/api/v1/plugin-catalog/install",Ht.parse(d))},async installPlan(d){let u=Ht.parse(d.marketplace===void 0?{entryId:d.entryId}:{entryId:d.entryId,marketplace:d.marketplace}),f=new URLSearchParams({entryId:u.entryId});return u.marketplace!==void 0&&f.set("marketplace",u.marketplace),(await r(`/api/v1/plugin-catalog/install-plan?${f.toString()}`,No,{signal:d.signal})).plan},async search(d){let u=e.string().parse(d.query);return await r(`/api/v1/plugin-catalog/search?q=${encodeURIComponent(u)}`,Hg,{signal:d.signal})},async status(d={}){return(await r("/api/v1/plugin-catalog",Uo,{signal:d.signal})).catalog}},marketplaces:{async add(d){let u=Fo.parse(d);return(await r("/api/v1/marketplaces",Wo,s("POST",u))).marketplace},async list(d={}){return(await r("/api/v1/marketplaces",Ho,{signal:d.signal})).marketplaces},async refresh(d={}){let u=Qo.parse(d.name===void 0?{}:{name:d.name});return(await r("/api/v1/marketplaces/refresh",Go,{...s("POST",u),signal:d.signal})).results},async remove(d){let u=Ke.parse(d.name);return{convertedPluginIds:(await r(`/api/v1/marketplaces/${encodeURIComponent(u)}`,$o,{method:"DELETE"})).convertedPluginIds}}},async disable(d){return(await r(H(d.pluginId,"/disable"),Cr,s("POST",{}))).plugin},async enable(d){return(await r(H(d.pluginId,"/enable"),Cr,s("POST",{}))).plugin},async getSettings(d){return r(H(d.pluginId,"/settings"),br,{signal:d.signal})},async getSource(d){return r(H(d.pluginId,"/source"),wo,{signal:d.signal})},async install(d){return g("/api/v1/plugins/install",h(d))},startInstall(d){return o("/api/v1/plugins/install",h(d))},installJobs:p,async list(d={}){return r("/api/v1/plugins",Bg,{signal:d.signal})},async listUpdateResults(d={}){return(await r("/api/v1/plugins/updates",ur,{signal:d.signal})).results},async reload(d={}){let u=d.pluginId?`?id=${encodeURIComponent(e.string().min(1).parse(d.pluginId))}`:"";return r(`/api/v1/plugins/reload${u}`,Ng,s("POST",{}))},async remove(d){return r(H(d.pluginId),Eo,{method:"DELETE"})},async token(d){let u=Lo.parse({rotate:d.rotate??!1});return r(H(d.pluginId,"/token"),qo,s("POST",u))},async updateSettings(d){let u=Co.parse({values:d.values});return r(H(d.pluginId,"/settings"),br,s("PUT",u))}}}var ub=J(ml(),1),mb=J(an(),1),hb=J(Te(),1),gb=J(Nr(),1),fb=J(Wr(),1),bb=J(Vr(),1),Yr=J(pn(),1),yb=J(xl(),1);function Rl(n){let t=new URL(n.url.href);return t.protocol==="http:"?t.protocol="ws:":t.protocol==="https:"&&(t.protocol="wss:"),t.pathname=n.preservePathPrefix?`${n.url.pathname.replace(/\/+$/u,"")}/ws`:"/ws",t.search="",t.hash="",t.href}function vb(n){try{let t=new URL(n);return t.protocol==="http:"||t.protocol==="https:"?t:null}catch{return null}}function Sb(){if(typeof location>"u")return null;let n=new URL(location.href);return n.protocol!=="http:"&&n.protocol!=="https:"?null:Rl({preservePathPrefix:!1,url:n})}function Tl(n){let{transport:t}=n;if(t.realtimeUrl)return t.realtimeUrl;let r=vb(t.baseUrl);if(r)return Rl({preservePathPrefix:!0,url:r});if(t.runtime==="browser"){let s=Sb();if(s)return s}throw new Error("BB SDK realtime requires an absolute baseUrl or realtimeUrl in this runtime.")}var wl=0,lt=1,Zr=1e3,xb=3e4,Rb=1.5;function Tb(n){return n?{kind:"thread-detail",threadId:n}:{kind:"thread-list"}}function wb(n){return n?{kind:"project-detail",projectId:n}:{kind:"project-list"}}function kb(n){return n?{kind:"environment-detail",environmentId:n}:{kind:"environment-list"}}function Pb(n){return n?{kind:"host-detail",hostId:n}:{kind:"host-list"}}function Ab(n){return n.selectorId===void 0||n.messageId===n.selectorId}function ts(n){return{close:()=>n.close(),onclose:null,onerror:null,onmessage:null,onopen:null,get readyState(){return n.readyState},send:t=>n.send(t)}}function ns(n){let t=ts(n);return n.onopen=()=>t.onopen?.(),n.onmessage=r=>t.onmessage?.({data:r.data}),n.onclose=()=>t.onclose?.(),n.onerror=()=>t.onerror?.(),t}function Ib(){return typeof WebSocket>"u"?null:n=>ns(new WebSocket(n))}function kl(n){return n.event!=="realtime:connection"}function Eb(n,t){return n.event===t}var es=class{listeners=new Set;targetSubscriptions=new Map;transport;lastConnectionEvent=null;reconnectDelayMs=Zr;reconnectingAfterUnexpectedClose=!1;reconnectTimer=null;rejectSocketReady=null;resolveSocketReady=null;socket=null;socketReadyPromise=null;constructor(t){this.transport=t.transport}subscribe(t){return this.addListener(t)}addListener(t){switch(t.event){case"thread:changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,selectorId:t.threadId,target:Tb(t.threadId)});case"project:changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,selectorId:t.projectId,target:wb(t.projectId)});case"environment:changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,selectorId:t.environmentId,target:kb(t.environmentId)});case"host:changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,selectorId:t.hostId,target:Pb(t.hostId)});case"system:changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,target:{kind:"system"}});case"system:config-changed":return this.activateListener({active:!0,callback:t.callback,event:t.event,target:{kind:"system"}});case"realtime:connection":return this.addConnectionListener({active:!0,callback:t.callback,event:t.event})}}addConnectionListener(t){let r=this.activateListener(t),s=this.lastConnectionEvent;return s&&queueMicrotask(()=>{t.active&&this.lastConnectionEvent===s&&this.callListener(t.callback,s)}),r}activateListener(t){if(this.listeners.add(t),kl(t)){this.addTarget(t.target);try{this.connectSocket().catch(r=>{t.active&&console.error("bb realtime connection failed",r)})}catch(r){throw this.removeListener(t),r}}return()=>this.removeListener(t)}removeListener(t){t.active&&(t.active=!1,this.listeners.delete(t),kl(t)&&this.removeTarget(t.target),this.closeSocketIfIdle())}addTarget(t){let r=zn(t),s=this.targetSubscriptions.get(r);if(s){s.count+=1;return}this.targetSubscriptions.set(r,{count:1,target:t}),this.socket?.readyState===lt&&this.sendTargetMessage("subscribe",t)}removeTarget(t){let r=zn(t),s=this.targetSubscriptions.get(r);if(s){if(s.count>1){s.count-=1;return}this.targetSubscriptions.delete(r),this.socket?.readyState===lt&&this.sendTargetMessage("unsubscribe",t)}}connectSocket(){if(this.targetSubscriptions.size===0)return Promise.resolve();if(this.socket&&(this.socket.readyState===lt||this.socket.readyState===wl))return this.ensureSocketReadyPromise();let t=this.transport.websocket??Ib();if(!t)throw new Error("BB SDK realtime requires a WebSocket implementation. Pass websocket when creating the transport.");let r=t(Tl({transport:this.transport}));this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.resetSocketReadyPromise();let s=this.ensureSocketReadyPromise(),i=this.reconnectingAfterUnexpectedClose;this.socket=r,this.emitConnection({state:"connecting",reconnected:i,reconnectDelayMs:null}),r.onopen=()=>{if(this.socket!==r)return;let p=this.reconnectingAfterUnexpectedClose;this.reconnectingAfterUnexpectedClose=!1,this.reconnectDelayMs=Zr;for(let m of this.targetSubscriptions.values())this.sendTargetMessage("subscribe",m.target);this.resolveSocketReadyPromise(),this.closeSocketIfIdle(),this.socket===r&&this.emitConnection({state:"connected",reconnected:p,reconnectDelayMs:null})},r.onmessage=p=>{this.handleSocketMessage(p)};let a=()=>{if(this.socket!==r)return;if(this.socket=null,this.clearSocketReadyPromise(new Error("bb realtime socket closed before it became ready.")),this.targetSubscriptions.size===0){this.lastConnectionEvent?.state!=="disconnected"&&this.emitConnection({state:"disconnected",reconnected:!1,reconnectDelayMs:null});return}this.reconnectingAfterUnexpectedClose=!0;let p=this.reconnectDelayMs;this.emitConnection({state:"disconnected",reconnected:!1,reconnectDelayMs:p}),!(this.reconnectTimer||this.socket)&&(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.reconnectDelayMs=Math.min(p*Rb,xb);try{this.connectSocket().catch(m=>{console.error("bb realtime reconnect failed",m)})}catch(m){console.error("bb realtime reconnect failed",m)}},p))};r.onclose=a;let l=!1;return r.onerror=()=>{l||(l=!0,r.close(),a())},s}closeSocketIfIdle(){if(this.targetSubscriptions.size>0)return;let t=!1;if(this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null,t=!0),this.reconnectingAfterUnexpectedClose=!1,this.reconnectDelayMs=Zr,this.clearSocketReadyPromise(new Error("bb realtime socket closed because there are no active targets.")),this.socket&&(this.socket.readyState===lt||this.socket.readyState===wl)){let r=this.socket;this.socket=null,this.emitConnection({state:"disconnected",reconnected:!1,reconnectDelayMs:null}),r.close();return}t&&this.emitConnection({state:"disconnected",reconnected:!1,reconnectDelayMs:null})}handleSocketMessage(t){if(typeof t.data!="string")return;let r;try{r=JSON.parse(t.data)}catch(i){console.error("bb realtime ignored malformed websocket message",i);return}if(typeof r=="object"&&r!==null&&"type"in r&&typeof r.type=="string"&&r.type!=="changed")return;let s=Qi.safeParse(r);if(!s.success){console.error("bb realtime ignored invalid websocket message",s.error);return}this.dispatchChangedMessage(s.data)}dispatchChangedMessage(t){switch(t.entity){case"thread":this.dispatchIdScopedChangedMessage("thread:changed",t);break;case"project":this.dispatchIdScopedChangedMessage("project:changed",t);break;case"environment":this.dispatchIdScopedChangedMessage("environment:changed",t);break;case"host":this.dispatchIdScopedChangedMessage("host:changed",t);break;case"system":this.dispatchSystemChangedMessage(t);break}}dispatchIdScopedChangedMessage(t,r){for(let s of this.listenerSnapshot())!Eb(s,t)||!s.active||!Ab({messageId:r.id,selectorId:s.selectorId})||this.callListener(s.callback,r)}dispatchSystemChangedMessage(t){for(let r of this.listenerSnapshot())r.active&&(r.event==="system:changed"&&this.callListener(r.callback,t),r.event==="system:config-changed"&&t.changes.includes("config-changed")&&this.callListener(r.callback,t))}ensureSocketReadyPromise(){if(this.socketReadyPromise||this.resetSocketReadyPromise(),!this.socketReadyPromise)throw new Error("BB SDK realtime socket readiness was not initialized.");return this.socketReadyPromise}resetSocketReadyPromise(){this.clearSocketReadyPromise(new Error("bb realtime socket closed before it became ready.")),this.socketReadyPromise=new Promise((t,r)=>{this.resolveSocketReady=t,this.rejectSocketReady=r})}resolveSocketReadyPromise(){this.resolveSocketReady&&(this.resolveSocketReady(),this.resolveSocketReady=null,this.rejectSocketReady=null)}clearSocketReadyPromise(t){this.rejectSocketReadyPromise(t),this.socketReadyPromise=null}rejectSocketReadyPromise(t){this.rejectSocketReady&&(this.rejectSocketReady(t),this.resolveSocketReady=null,this.rejectSocketReady=null)}sendTargetMessage(t,r){if(!this.socket||this.socket.readyState!==lt)return;let s={type:t,target:r};this.socket.send(JSON.stringify(s))}emitConnection(t){this.lastConnectionEvent=t;for(let r of this.listenerSnapshot())r.event!=="realtime:connection"||!r.active||this.callListener(r.callback,t)}listenerSnapshot(){return[...this.listeners]}callListener(t,r){try{t(r)}catch(s){console.error("bb realtime listener failed",s)}}};function Pl(n){return new es(n)}function Cb(n){return typeof n=="string"?n:Array.isArray(n)?Buffer.concat(n).toString("utf8"):Buffer.isBuffer(n)?n.toString("utf8"):Buffer.from(new Uint8Array(n)).toString("utf8")}function jb(n){let t=new Yr.default(n),r=ts(t);return t.on("open",()=>r.onopen?.()),t.on("message",s=>r.onmessage?.({data:Cb(s)})),t.on("close",()=>r.onclose?.()),t.on("error",()=>r.onerror?.()),r}function Al(){return n=>typeof WebSocket<"u"?ns(new WebSocket(n)):jb(n)}function le(n,t){throw new Error(t??`Unexpected value: ${String(n)}`)}function _b(n,t){return n===null||t.status==="loading"?null:t.provider===null?n:t.provider.displayName}function Mb({environment:n,host:t,providerLookup:r}){let s=n.hostLifecycle==="active"?null:n.hostLifecycle,i=s??(n.status==="destroyed"?"destroyed":n.status==="provisioning"?"provisioning":null),a=i==="removed"?"Unavailable \u2014 machine removed":i==="removing"?"Machine removal in progress":i==="cleanup-failed"?"Machine cleanup failed":i==="destroyed"?"Environment unavailable":i==="provisioning"?"Provisioning":null,l=_b(n.environmentProviderId,r),p=t.locality==="remote"?"Remote":"Local",m=l??(t.locality==="remote"?"Working remotely":"Working locally"),o=l??p;return{modeLabel:(s?a:null)??n.name??a??m,compactModeLabel:(s?a:null)??n.name??a??o,providerLabel:l,lifecycle:i,id:n.id}}function mn(n){let{tool:t,presentation:r}=n.subject;return{title:n.reason??r.label.pending,tool:t,headline:Il(r.title),detail:Il(r.detail),icon:r.icon,tint:r.tint??null}}function Il(n){return n===void 0||n.trim().length===0?null:n}function El(n){return[`Tool: ${n.tool}`,...n.headline!==null?[n.headline]:[],...n.detail!==null?[n.detail]:[]]}function Db(n){if(n===null)return[];let t=[];return n.accessibility&&t.push("macOS accessibility"),n.launchServices&&t.push("macOS launch services"),n.calendar&&t.push("macOS calendar"),n.reminders&&t.push("macOS reminders"),n.preferences!=="none"&&t.push(`macOS preferences (${n.preferences.replace("_"," ")})`),n.contacts!=="none"&&t.push(`macOS contacts (${n.contacts.replace("_"," ")})`),n.automations==="all"?t.push("macOS automation (all apps)"):n.automations!=="none"&&n.automations.bundleIds.length>0&&t.push(n.automations.bundleIds.length===1?"macOS automation (1 app)":`macOS automation (${n.automations.bundleIds.length} apps)`),t}function rs(n){let t=[];return n.network?.enabled===!0&&t.push("Network access"),n.fileSystem&&(n.fileSystem.read.length>0&&t.push(n.fileSystem.read.length===1?"Read 1 path":`Read ${n.fileSystem.read.length} paths`),n.fileSystem.write.length>0&&t.push(n.fileSystem.write.length===1?"Write 1 path":`Write ${n.fileSystem.write.length} paths`)),[...t,...Db("macos"in n?n.macos:null)]}function Ob(n){return n.map(t=>{switch(t.type){case"read":return`Read ${t.path}`;case"listFiles":return t.path?`List files in ${t.path}`:"List files";case"search":return t.query?`Search for ${t.query}${t.path?` in ${t.path}`:""}`:t.path?`Search in ${t.path}`:"Search files";case"unknown":return t.command;default:return le(t)}})}function Cl(n,t){if(t===null)return null;let r=rs(t);return r.length>0?`${n}: ${r.join(", ")}`:null}function Lb(n){if(bt(n.payload))return n.payload.questions.map(t=>t.prompt);if(!Me(n.payload))return[];switch(n.payload.subject.kind){case"command":{let t=Ob(n.payload.subject.actions).map(s=>`Action: ${s}`),r=Cl("Session grant",n.payload.subject.sessionGrant);return[`Command: ${n.payload.subject.command}`,...n.payload.subject.cwd?[`Cwd: ${n.payload.subject.cwd}`]:[],...t,...r?[r]:[]]}case"file_change":{let t=Cl("Session grant",n.payload.subject.sessionGrant);return[`Item: ${n.payload.subject.itemId}`,...n.payload.subject.writeScope?[`Write root: ${n.payload.subject.writeScope}`]:[],...t?[t]:[]]}case"permission_grant":{let t=rs(n.payload.subject.permissions);return[...n.payload.subject.toolName?[`Tool: ${n.payload.subject.toolName}`]:[],...t.map(r=>`Permission: ${r}`)]}case"plan":return n.payload.subject.planFilePath?[`Plan file: ${n.payload.subject.planFilePath}`]:[];case"tool_use":return El(mn({...n.payload,subject:n.payload.subject}));default:return le(n.payload.subject)}}function qb(n){return{network:n.network?.enabled===!0?{enabled:!0}:null,fileSystem:n.fileSystem?{read:n.fileSystem.read,write:n.fileSystem.write}:null}}function Ub(n){switch(n){case"allow_once":return"approved";case"allow_for_session":return"approved for this session";case"deny":return"denied";default:return le(n)}}function Bb(n,t){return Me(n.payload)?n.payload.subject.kind==="permission_grant"?qb(n.payload.subject.permissions):t!=="allow_for_session"?null:n.payload.subject.kind==="command"||n.payload.subject.kind==="file_change"?n.payload.subject.sessionGrant:null:null}function zb(n,t){return t==="deny"?{decision:t}:{decision:t,grantedPermissions:Bb(n,t)}}function Nb({question:n,value:t}){return n.options?.find(r=>r.value===t)?.label??t}function Hb(n){let{interaction:t}=n;if(bt(t.payload))return t.payload.questions[0]?.prompt??"User answer requested";if(!Me(t.payload))return t.payload.title;if(t.payload.reason)return t.payload.reason;switch(t.payload.subject.kind){case"command":return t.payload.subject.command;case"file_change":return"File changes pending approval";case"plan":return"Plan ready for review";case"tool_use":return mn({...t.payload,subject:t.payload.subject}).title;case"permission_grant":break;default:return le(t.payload.subject)}return t.payload.subject.toolName??"Permission request"}function Fb(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function jl(n){return Fb(n)?n:null}function Ee(n,t){if(typeof n=="string"){let s=n.replace(/\s+/g," ").trim();return s.length===0?null:s}if(Array.isArray(n)){for(let s of n){let i=Ee(s,t);if(i)return i}return null}let r=jl(n);if(!r)return null;if(typeof r.message=="string"){let s=Ee(r.message,t);if(s)return s}for(let s of t?.legacyKeys??["detail"]){let i=Ee(r[s],t);if(i)return i}return null}var _l=75e3,Wb=new Set(["arrayBuffer","blob","bytes","formData","json","text"]),$b={legacyKeys:["detail","error"]};function Qb(n){let t=n/1e3;return Number.isInteger(t)?t===1?"1 second":`${t} seconds`:`${n} ms`}var de=class extends Error{constructor(t){super(`BB request timed out after ${Qb(t)}.`),this.name="BbRequestTimeoutError"}},hn=class extends Error{body;code;status;constructor(t){super(`HTTP ${t.status}: ${t.message}`),this.name="BbHttpError",this.body=t.body,this.code=t.code,this.status=t.status}};function Ml(n){return Kb(n.timeoutMs),async(t,r)=>{let s=AbortSignal.timeout(n.timeoutMs),i=r?.signal?AbortSignal.any([r.signal,s]):s,a={requestSignal:i,timeoutSignal:s,timeoutMs:n.timeoutMs};try{let l=await fetch(t,{...r,signal:i});return Ll({context:a,response:l})}catch(l){throw ss(a,l)?new de(n.timeoutMs):l}}}async function Dl(n){return(await gn(n)).json()}async function Ol(n){await gn(n)}async function gn(n){let t;try{t=await n}catch(r){throw Vb(r,"ECONNREFUSED")?new Error("Cannot connect to BB server. Ensure it is running and BB_SERVER_URL is correct."):r}if(!t.ok){let{body:r,code:s,message:i}=await Yb(t);throw new hn({body:r,code:s,message:i,status:t.status})}return t}async function Gb(n){try{return await n.read()}catch(t){throw ss(n.context,t)?new de(n.context.timeoutMs):t}}function Ll(n){let{context:t,response:r}=n,s;return new Proxy(r,{get(i,a){if(Wb.has(a)){let l=Reflect.get(i,a,i);if(typeof l=="function")return()=>Gb({context:t,read:l.bind(i)})}switch(a){case"body":return i.body===null?null:(s??=Jb({context:t,stream:i.body}),s);case"clone":return()=>Ll({context:t,response:i.clone()});default:{let l=Reflect.get(i,a,i);return typeof l=="function"?l.bind(i):l}}}})}function Jb(n){let t=null,r=()=>(t??=n.stream.getReader(),t);return new ReadableStream({async pull(s){try{let i=await r().read();if(i.done){s.close();return}s.enqueue(i.value)}catch(i){if(ss(n.context,i)){s.error(new de(n.context.timeoutMs));return}s.error(i)}},cancel(s){return r().cancel(s)}})}function ss(n,t){return n.timeoutSignal.aborted&&t===n.timeoutSignal.reason?!0:n.timeoutSignal.aborted&&n.requestSignal.reason===n.timeoutSignal.reason&&t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")}function Kb(n){if(!Number.isFinite(n)||n<0)throw new RangeError("BB request timeout must be a non-negative finite number.")}function Vb(n,t){if(!(n instanceof TypeError))return!1;let{cause:r}=n;return!r||typeof r!="object"?!1:"code"in r&&r.code===t}function Xb(n){if(n===null||typeof n!="object"||Array.isArray(n))return null;if("code"in n&&typeof n.code=="string")return n.code;if("ok"in n&&n.ok===!1&&"error"in n){let t=n.error;if(typeof t=="object"&&t!==null&&"code"in t&&typeof t.code=="string")return t.code}return null}async function Yb(n){let t;try{t=await n.text()}catch(a){if(a instanceof de)throw a;t=""}let r=t.replace(/\s+/g," ").trim();if(r.length===0)return{body:null,code:null,message:n.statusText};if(!((n.headers.get("content-type")?.includes("application/json")??!1)||r.startsWith("{")||r.startsWith("[")))return{body:null,code:null,message:r.startsWith("<")?n.statusText||`Request failed with status ${n.status}`:r};try{let a=JSON.parse(r);return{body:a,code:Xb(a),message:Ee(a,$b)??r}}catch{return{body:null,code:null,message:r}}}function ql({transport:n}){let t=()=>n.api.v1["desktop-browsers"],r=s=>n.readJson(t().tabs.$post({json:s}));return{listInstances:s=>n.readJson(t().instances.$post({json:s})),listTabs:r,createTab:s=>n.readJson(t().create.$post({json:s})),acquireControl:s=>n.readJson(t().acquire.$post({json:s})),openConnection:s=>n.readJson(t().connection.$post({json:s})),releaseControl:s=>n.readJson(t().release.$post({json:s})),revealTab:s=>n.readJson(t().reveal.$post({json:s})),closeTab:s=>n.readJson(t().close.$post({json:s})),captureTab:s=>n.readJson(t().capture.$post({json:s})),listImportSources:s=>n.readJson(t()["import-sources"].$post({json:s})),importCookies:s=>n.readJson(t()["import-cookies"].$post({json:s})),subscribe(s){let i=!1,a,l="",p={hostId:s.hostId,instanceId:s.instanceId,generation:s.generation,threadId:s.threadId},m=async()=>{try{let o=await r(p),g=JSON.stringify(o);!i&&g!==l&&(l=g,s.onChange(o))}catch(o){i||s.onError(o instanceof Error?o:new Error(String(o)))}finally{i||(a=setTimeout(()=>{m()},2e3))}};return m(),{dispose(){i=!0,clearTimeout(a)}}}}}function c(n){return n===void 0?[]:[{init:{signal:n}}]}async function fn(n,t){return n.readJson(n.api.v1.system["execution-options"].$get({query:{environmentId:t.environmentId,hostId:t.hostId,projectId:t.projectId,providerId:t.providerId}},...c(t.signal)))}var Zb=e.object({ok:e.literal(!0)});function ey(n){let t={};return n.mergeBaseBranch!==void 0&&(t.mergeBaseBranch=n.mergeBaseBranch),n.name!==void 0&&(t.name=n.name),lo.parse(t)}function ty(n){return{mergeBaseBranch:n.mergeBaseBranch}}function bn(n){switch(n.target){case"uncommitted":return{target:n.target};case"branch_committed":case"all":return{target:n.target,mergeBaseBranch:n.mergeBaseBranch};case"commit":return{target:n.target,sha:n.sha}}}function ny(n){switch(n.target){case"uncommitted":return{path:n.path,side:n.side,target:n.target};case"branch_committed":case"all":return{mergeBaseRef:n.mergeBaseRef,path:n.path,side:n.side,target:n.target};case"commit":return{path:n.path,sha:n.sha,side:n.side,target:n.target}}}function ry(n){return{...n.query!==void 0?{query:n.query}:{},...n.limit!==void 0?{limit:n.limit}:{},...n.selectedBranch!==void 0?{selectedBranch:n.selectedBranch}:{}}}function sy(n){return{includeDirectories:n.includeDirectories,includeFiles:n.includeFiles,limit:n.limit,query:n.query}}function Ul(n){let{transport:t}=n;return{async archiveThreads(r){return t.readJson(t.api.v1.environments[":id"]["archive-threads"].$post({param:{id:r.environmentId}}))},async commit(r){let s=await t.readJson(t.api.v1.environments[":id"].actions.$post({param:{id:r.environmentId},json:{action:"commit"}}));return cr.parse(s)},async diff(r){return t.readJson(t.api.v1.environments[":id"].diff.$get({param:{id:r.environmentId},query:bn(r)},...c(r.signal)))},async diffBranches(r){return t.readJson(t.api.v1.environments[":id"].diff.branches.$get({param:{id:r.environmentId},query:ry(r)},...c(r.signal)))},async diffFile(r){return t.readJson(t.api.v1.environments[":id"].diff.file.$get({param:{id:r.environmentId},query:ny(r)},...c(r.signal)))},async diffFiles(r){return t.readJson(t.api.v1.environments[":id"].diff.files.$get({param:{id:r.environmentId},query:{...bn(r),...r.ignoreWhitespace===!0?{ignoreWhitespace:"true"}:{}}},...c(r.signal)))},async diffPatch(r){return t.readJson(t.api.v1.environments[":id"].diff.patch.$post({param:{id:r.environmentId},json:{paths:r.paths,target:r.target,ignoreWhitespace:r.ignoreWhitespace}},...c(r.signal)))},async experimental_diffViewed(r){return r.paths!==void 0?t.readJson(t.api.v1.environments[":id"].diff.viewed.$post({param:{id:r.environmentId},json:{...bn(r),paths:r.paths}},...c(r.signal))):t.readJson(t.api.v1.environments[":id"].diff.viewed.$get({param:{id:r.environmentId},query:bn(r)},...c(r.signal)))},async experimental_markDiffViewed(r){return t.readJson(t.api.v1.environments[":id"].diff.viewed.$put({param:{id:r.environmentId},json:{target:r.target,path:r.path,revision:r.revision}}))},async experimental_clearDiffViewed(r){return t.readJson(t.api.v1.environments[":id"].diff.viewed.$delete({param:{id:r.environmentId},json:{target:r.target,path:r.path}}))},async list(r){return t.readJson(t.api.v1.environments.$get({query:{...r?.projectId===void 0?{}:{projectId:r.projectId},...r?.hostId===void 0?{}:{hostId:r.hostId},...r?.environmentProviderId===void 0?{}:{environmentProviderId:r.environmentProviderId},...r?.instanceKey===void 0?{}:{instanceKey:r.instanceKey},...r?.status===void 0?{}:{status:r.status},...r?.path===void 0?{}:{path:r.path},...r?.limit===void 0?{}:{limit:String(r.limit)},...r?.offset===void 0?{}:{offset:String(r.offset)}}},...c(r?.signal)))},async listProviders(r){return(await t.readJson(t.api.v1.system["environment-providers"].$get({query:{...r?.projectId===void 0?{}:{projectId:r.projectId},...r?.hostId===void 0?{}:{hostId:r.hostId}}},...c(r?.signal)))).providers},async experimental_cleanup(r){return t.readJson(t.api.v1.environments[":id"].cleanup.$post({param:{id:r.environmentId},query:{recover:r.recover===!0?"true":"false"}}))},async delete(r){let s=await t.readJson(t.api.v1.environments[":id"].$delete({param:{id:r.environmentId}}));return Zb.parse(s)},async get(r){let s=await t.readJson(t.api.v1.environments[":id"].$get({param:{id:r.environmentId}},...c(r.signal)));return St.parse(s)},async paths(r){return t.readJson(t.api.v1.environments[":id"].paths.$get({param:{id:r.environmentId},query:sy(r)},...c(r.signal)))},async status(r){return t.readJson(t.api.v1.environments[":id"].status.$get({param:{id:r.environmentId},query:ty(r)},...c(r.signal)))},async update(r){return t.readJson(t.api.v1.environments[":id"].$patch({param:{id:r.environmentId},json:ey(r)}))}}}function Bl(n){let{transport:t}=n;return{async read(r){return t.readJson(t.api.v1.files.read.$post({json:{hostId:r.hostId,path:r.path,rootPath:r.rootPath}},...c(r.signal)))},async write(r){return t.readJson(t.api.v1.files.write.$post({json:r}))},async list(r){return t.readJson(t.api.v1.files.list.$post({json:{excludeNames:r.excludeNames,hostId:r.hostId,includeHidden:r.includeHidden,limit:r.limit,path:r.path,query:r.query}},...c(r.signal)))},async listPaths(r){return t.readJson(t.api.v1.files.paths.$post({json:{excludeNames:r.excludeNames,hostId:r.hostId,includeDirectories:r.includeDirectories,includeFiles:r.includeFiles,includeHidden:r.includeHidden,limit:r.limit,path:r.path,query:r.query}},...c(r.signal)))},async mkdir(r){return t.readJson(t.api.v1.files.mkdir.$post({json:r}))},async move(r){return t.readJson(t.api.v1.files.move.$post({json:r}))},async remove(r){return t.readJson(t.api.v1.files.remove.$post({json:r}))},async createPreview(r){return t.readJson(t.api.v1.files.previews.$post({json:{hostId:r.hostId,rootPath:r.rootPath,ttlMs:r.ttlMs}},...c(r.signal)))}}}function zl(n){let{transport:t}=n;return{async experimental_create(r){let s=await t.readJson(t.api.v1.hosts.$post({json:{machineProviderId:r.machineProviderId,inputs:r.inputs,...r.key===void 0?{}:{key:r.key}}},...c(r.signal)));if(r.wait===!1)return s;for(;;){if(r.signal?.throwIfAborted(),s.lifecycle.phase==="active")return s;if(s.lifecycle.phase==="removing"||s.lifecycle.phase==="destroyed")throw new Error(s.lifecycle.message??"Machine creation cancelled");await new Promise(i=>setTimeout(i,1e3)),s=await this.get({hostId:s.id,signal:r.signal})}},async experimental_getEnrollmentCommand(r){return t.readJson(t.api.v1.hosts[":id"]["enrollment-command"].$get({param:{id:r.hostId}},...c(r.signal)))},async experimental_reconnect(r){return t.readJson(t.api.v1.hosts[":id"]["reconnect-commands"].$post({param:{id:r.hostId}},...c(r.signal)))},async createJoinCode(){return t.readJson(t.api.v1.hosts["join-codes"].$post({json:{}}))},async delete(r){return await t.readVoid(t.api.v1.hosts[":id"].$delete({param:{id:r.hostId},query:r.force?{force:"true"}:{}})),{ok:!0}},async experimental_deleteOldServerCopy(r){return t.readJson(t.api.v1.hosts[":id"]["old-server-copy"].$delete({param:{id:r.hostId}}))},async directory(r){return t.readJson(t.api.v1.hosts[":id"].directory.$get({param:{id:r.hostId},query:{path:r.path}},...c(r.signal)))},async experimental_discoverRepos(r){return t.readJson(t.api.v1.hosts[":id"]["discovered-repos"].$get({param:{id:r.hostId}},...c(r.signal)))},async get(r){return t.readJson(t.api.v1.hosts[":id"].$get({param:{id:r.hostId}},...c(r.signal)))},async cloneDefaultPath(r){return t.readJson(t.api.v1.hosts[":id"]["clone-default-path"].$get({param:{id:r.hostId},query:{projectId:r.projectId}},...c(r.signal)))},async installProviderCli(r){return(await(await t.resolve(t.api.v1.hosts[":id"]["provider-clis"].install.$post({param:{id:r.hostId},json:{provider:r.provider,actionKind:r.actionKind}}))).text()).split(/\r?\n/u).filter(a=>a.trim().length>0).map(a=>yo.parse(JSON.parse(a)))},async list(r){return t.readJson(t.api.v1.hosts.$get({query:{...r?.includeCreating===void 0?{}:{includeCreating:r.includeCreating?"true":"false"},...r?.type===void 0?{}:{type:r.type}}},...c(r?.signal)))},async experimental_listProviders(r){return(await t.readJson(t.api.v1.system["machine-providers"].$get({},...c(r?.signal)))).providers},async pathsExist(r){return t.readJson(t.api.v1.hosts[":id"].paths.exist.$post({param:{id:r.hostId},json:{paths:r.paths}},...c(r.signal)))},async pickFolder(r){return t.readJson(t.api.v1.hosts[":id"]["pick-folder"].$post({param:{id:r.hostId},json:{clientHostId:r.clientHostId}},...c(r.signal)))},async providerCliStatus(r){return t.readJson(t.api.v1.hosts[":id"]["provider-clis"].status.$get({param:{id:r.hostId}},...c(r.signal)))},async experimental_resume(r){return t.readJson(t.api.v1.hosts[":id"].resume.$post({param:{id:r.hostId}}))},async experimental_retryCleanup(r){return t.readJson(t.api.v1.hosts[":id"]["retry-cleanup"].$post({param:{id:r.hostId}}))},async retryUpdate(r){return t.readJson(t.api.v1.hosts[":id"]["retry-update"].$post({param:{id:r.hostId}}))},async experimental_reconcile(r){return t.readJson(t.api.v1.hosts[":id"].reconcile.$post({param:{id:r.hostId}}))},async experimental_suspend(r){return t.readJson(t.api.v1.hosts[":id"].suspend.$post({param:{id:r.hostId}}))},async update(r){return t.readJson(t.api.v1.hosts[":id"].$patch({param:{id:r.hostId},json:{name:r.name}}))}}}var iy=/filename="([^"]+)"/u,oy="x-bb-archive-sha256",ay=/^[0-9a-f]{64}$/u;function ly(n){return(n===null?null:iy.exec(n))?.[1]??"bb-server-export"}function Nl(n){let{transport:t}=n;return{async checkMove(r){return t.readJson(t.api.v1.server.move.check.$post({json:{targetHostId:r.targetHostId,serverUrl:r.serverUrl}},...c(r.signal)))},async startMove(r){return t.readJson(t.api.v1.server.move.$post({json:{targetHostId:r.targetHostId,serverUrl:r.serverUrl,stopRunningWork:r.stopRunningWork,archiveExistingTargetServerData:r.archiveExistingTargetServerData}}))},async moveStatus(r){return t.readJson(t.api.v1.server.move.$get({},...c(r?.signal)))},async cancelMove(){return t.readJson(t.api.v1.server.move.cancel.$post())},async export(r){let s=await t.resolve(t.api.v1.server.export.$post({},...c(r?.signal)));if(s.body===null)throw new Error("The server returned an empty export");let i=s.headers.get(oy);if(i===null||!ay.test(i))throw await s.body.cancel().catch(()=>{}),new Error("The server did not send a SHA-256 digest for the export");return{fileName:ly(s.headers.get("content-disposition")),body:s.body,sha256:i}}}}function dy(n){return{name:n.name}}function cy(n){return n.type==="local_path"?{hostId:n.hostId,path:n.path,type:n.type}:{hostId:n.hostId,type:n.type,...n.remoteUrl!==void 0?{remoteUrl:n.remoteUrl}:{},...n.targetPath!==void 0?{targetPath:n.targetPath}:{}}}function py(n){return{isDefault:n.isDefault,path:n.path,type:n.type}}function uy(n){if("name"in n&&typeof n.name=="string")return n.name}function my(n){return{...n.include===void 0?{}:{include:n.include},...n.includePersonal===void 0?{}:{includePersonal:n.includePersonal?"true":"false"}}}function hy(n){if("type"in n&&typeof n.type=="string")return n.type}function gy(n){return"arrayBuffer"in n}async function fy(n){return gy(n)?n.arrayBuffer():ArrayBuffer.isView(n)?Uint8Array.from(n).buffer:n.slice(0)}function by(n){let t=n.filename??uy(n.clientFile);if(!t||t.trim().length===0)throw new Error("Project attachment filename must not be empty");return t}function yy(n){let t=n.split("/");if(n.includes("\0")||n.includes("\\")||t.some(r=>r===""||r==="."||r===".."))throw new Error(`Invalid file path: ${n}`);return t.map(encodeURIComponent).join("/")}function vy(n,t){if(t.startsWith("image/")&&!t.startsWith("image/svg+xml"))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(n),!0}catch{return!1}}var yn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function Sy(n){let t="";for(let r=0;r<n.length;r+=3){let s=n[r]??0,i=n[r+1],a=n[r+2],l=s<<16|(i??0)<<8|(a===void 0?0:a);t+=yn.charAt(l>>18&63),t+=yn.charAt(l>>12&63),t+=i===void 0?"=":yn.charAt(l>>6&63),t+=a===void 0?"=":yn.charAt(l&63)}return t}function Hl(n){let{transport:t}=n;return{attachments:{async copy(i){let{projectId:a,...l}=i;await t.readVoid(t.api.v1.projects[":id"].attachments.copy.$post({param:{id:a},json:l}))},async read(i){let a=await t.resolve(t.api.v1.projects[":id"].attachments.content.$get({param:{id:i.projectId},query:{path:i.path}},...c(i.signal))),l=new Uint8Array(await a.arrayBuffer());return{bytes:l,mimeType:a.headers.get("content-type")??"application/octet-stream",sizeBytes:l.byteLength}},async upload(i){let a=by(i),l=i.mimeType??hy(i.clientFile)??"",p=i.clientFile instanceof Blob&&i.clientFile.type===l?i.clientFile:new Blob([await fy(i.clientFile)],{type:l}),m=new FormData;m.set("file",p,a);let o=t.baseUrl.replace(/\/$/u,""),g=await t.resolve(t.fetch(`${o}/api/v1/projects/${encodeURIComponent(i.projectId)}/attachments`,{body:m,method:"POST"}));return Yi.parse(await g.json())}},async branches(i){let{projectId:a,signal:l,...p}=i;return t.readJson(t.api.v1.projects[":id"].branches.$get({param:{id:a},query:p},...c(l)))},async commands(i){let{projectId:a,signal:l,...p}=i;return t.readJson(t.api.v1.projects[":id"].commands.$get({param:{id:a},query:p},...c(l)))},async create(i){return t.readJson(t.api.v1.projects.$post({json:i}))},async delete(i){return await t.readVoid(t.api.v1.projects[":id"].$delete({param:{id:i.projectId}})),{ok:!0}},async defaultExecutionOptions(i){return t.readJson(t.api.v1.projects[":id"]["default-execution-options"].$get({param:{id:i.projectId},query:{}},...c(i.signal)))},async fileContent(i){let{projectId:a,path:l,signal:p,environmentId:m,hostId:o}=i,g=yy(l),h=m!==void 0?`/environments/${encodeURIComponent(m)}/files/${g}`:o!==void 0?`/projects/${encodeURIComponent(a)}/hosts/${encodeURIComponent(o)}/files/${g}`:`/projects/${encodeURIComponent(a)}/files/${g}`,b=await t.resolve(t.fetch(`${t.baseUrl.replace(/\/+$/u,"")}/api/v1${h}`,p===void 0?void 0:{signal:p})),y=new Uint8Array(await b.arrayBuffer()),d=b.headers.get("content-type")??"application/octet-stream",u=vy(y,d)?"utf8":"base64";return{content:u==="utf8"?new TextDecoder().decode(y):Sy(y),contentEncoding:u,mimeType:d,sizeBytes:y.byteLength}},async files(i){let{projectId:a,signal:l,...p}=i;return t.readJson(t.api.v1.projects[":id"].files.$get({param:{id:a},query:p},...c(l)))},async machineEnvironment(i){return t.readJson(t.api.v1.projects[":id"]["machine-environment"].$get({param:{id:i.projectId}}))},async replaceMachineEnvironment(i){return t.readJson(t.api.v1.projects[":id"]["machine-environment"].$put({param:{id:i.projectId},json:{variables:i.variables}}))},async setMachineEnvironmentVariable(i){return t.readJson(t.api.v1.projects[":id"]["machine-environment"].$post({param:{id:i.projectId},json:{name:i.name,value:i.value,note:i.note}}))},async deleteMachineEnvironmentVariable(i){return t.readJson(t.api.v1.projects[":id"]["machine-environment"].$delete({param:{id:i.projectId},json:{name:i.name}}))},async get(i){return t.readJson(t.api.v1.projects[":id"].$get({param:{id:i.projectId}},...c(i.signal)))},async list(i={}){let{signal:a,...l}=i;return t.readJson(t.api.v1.projects.$get({query:my(l)},...c(a)))},async paths(i){let{projectId:a,signal:l,...p}=i;return t.readJson(t.api.v1.projects[":id"].paths.$get({param:{id:a},query:p},...c(l)))},async promptHistory(i){return t.readJson(t.api.v1.projects[":id"]["prompt-history"].$get({param:{id:i.projectId},query:{limit:i.limit}},...c(i.signal)))},async reorder(i){return t.readJson(t.api.v1.projects[":id"].order.$patch({param:{id:i.projectId},json:{previousProjectId:i.previousProjectId,nextProjectId:i.nextProjectId}}))},async sidebarBootstrap(i={}){return t.readJson(t.api.v1["sidebar-bootstrap"].$get({},...c(i.signal)))},sources:{async add(i){return t.readJson(t.api.v1.projects[":id"].sources.$post({param:{id:i.projectId},json:cy(i)}))},async delete(i){return await t.readVoid(t.api.v1.projects[":id"].sources[":sourceId"].$delete({param:{id:i.projectId,sourceId:i.sourceId}})),{ok:!0}},async update(i){return t.readJson(t.api.v1.projects[":id"].sources[":sourceId"].$patch({param:{id:i.projectId,sourceId:i.sourceId},json:py(i)}))}},async update(i){return t.readJson(t.api.v1.projects[":id"].$patch({param:{id:i.projectId},json:dy(i)}))}}}function Fl(n){let{transport:t}=n;return{async catalog(){return t.readJson(t.api.v1.system.providers.catalog.$get())},async setEnabled(r){return t.readJson(t.api.v1.system.providers[":id"].enabled.$put({param:{id:r.providerId},json:{enabled:r.enabled}}))},async list(r={}){return t.readJson(t.api.v1.system.providers.$get({query:{capability:r.capability,environmentId:r.environmentId,hostId:r.hostId}},...c(r.signal)))},async models(r={}){return fn(t,r)}}}function Wl({transport:n}){return{async list(t={}){let{signal:r,...s}=t;return n.readJson(n.api.v1["prompt-history"].$get({query:s},...c(r)))}}}async function vn(n){try{return await n()}catch{return null}}function xy(n){return{environmentId:n.environmentId??null,id:n.id,parentNotifications:n.parentNotifications,parentThreadId:n.parentThreadId??null,pinnedAt:n.pinnedAt,projectId:n.projectId,status:n.status,title:n.title??null}}function $l(n){let{transport:t}=n;return{async get(r={}){let s=r.projectId,i=r.signal,a=r.threadId,[l,p]=await Promise.all([s?vn(()=>t.readJson(t.api.v1.projects[":id"].$get({param:{id:s}},...c(i)))):Promise.resolve(null),a?vn(()=>t.readJson(t.api.v1.threads[":id"].$get({param:{id:a}},...c(i)))):Promise.resolve(null)]),m=p===null?null:await vn(async()=>(await t.readJson(t.api.v1.threads[":id"].timeline.$get({param:{id:p.id},query:{summaryOnly:"true"}},...c(i)))).pendingTodos);return{childThreads:p===null?null:await vn(()=>t.readJson(t.api.v1.threads.$get({query:{parentThreadId:p.id}},...c(i)))),pendingTodos:m,project:l,thread:p===null?null:xy(p)}}}}function Ql(n){let{transport:t}=n;async function r(i,a,l){let p=t.baseUrl.replace(/\/$/u,""),m=await t.resolve(t.fetch(`${p}${i}`,l));return a.parse(await m.json())}return{async getContent(i){return t.readJson(t.api.v1.projects[":id"].skills.content.$get({param:{id:i.projectId},query:{skillId:i.skillId,path:i.path,environmentId:i.environmentId??""}},...c(i.signal)))},async list(i){return t.readJson(t.api.v1.projects[":id"].skills.$get({param:{id:i.projectId},query:{environmentId:i.environmentId??""}},...c(i.signal)))},async listFiles(i){return t.readJson(t.api.v1.projects[":id"].skills.files.$get({param:{id:i.projectId},query:{skillId:i.skillId,environmentId:i.environmentId??""}},...c(i.signal)))},registry:{async detail(i){let a=new URLSearchParams({source:i.source,skillId:i.skillId});return r(`/api/v1/skills-registry/detail?${a.toString()}`,to,{signal:i.signal})},async entries(i){let a=no.parse({ids:[...i.registrySkillIds]});return r("/api/v1/skills-registry/entries",ro,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(a),signal:i.signal})},async get(i){let a=new URLSearchParams({id:i.registrySkillId});return r(`/api/v1/skills-registry/entry?${a.toString()}`,qt,{signal:i.signal})},async install(i){let a=so.parse(i);return r("/api/v1/skills-registry/install",io,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(a)})},async repositoryStars(i){let a=new URLSearchParams({source:i.source});return r(`/api/v1/skills-registry/repository-stars?${a.toString()}`,eo,{signal:i.signal})},async search(i={}){let a=new URLSearchParams({page:String(i.page??0),perPage:String(i.perPage??24)});return i.query?.trim()&&a.set("q",i.query.trim()),r(`/api/v1/skills-registry?${a.toString()}`,Zi,{signal:i.signal})}},async remove(i){let a={skillId:i.skillId,environmentId:i.environmentId};return t.readJson(t.api.v1.projects[":id"].skills.$delete({param:{id:i.projectId},json:a}))},async update(i){return t.readJson(t.api.v1.projects[":id"].skills.content.$patch({param:{id:i.projectId},json:{skillId:i.skillId,environmentId:i.environmentId,content:i.content,revision:i.revision}}))}}}function Gl(n){let{transport:t}=n;return{async get(r={}){return(await t.readJson(t.api.v1.system.config.$get({},...c(r.signal)))).appearance},async catalog(r={}){return t.readJson(t.api.v1.settings.themes.$get({},...c(r.signal)))},async resolve(r){return t.readJson(t.api.v1.settings.themes[":id"].$get({param:{id:r.themeId}},...c(r.signal)))},async set(r){if(typeof r=="string"){let s=(await t.readJson(t.api.v1.system.config.$get())).appearance;return t.readJson(t.api.v1.settings.appearance.$put({json:{themeId:r,faviconColor:s.faviconColor}}))}return t.readJson(t.api.v1.settings.appearance.$put({json:r}))}}}function Ry(n){return n?.force===void 0?{}:{force:n.force?"true":"false"}}function Ty(n){return n?.force===void 0?{}:{force:n.force?"true":"false"}}function Jl(n){let{transport:t}=n;return{uiPreferences:{async list(s){return t.readJson(t.api.v1.preferences.ui.$get({},...c(s?.signal)))},async set(s){return await t.readJson(t.api.v1.preferences.ui[":key"].$put({json:{expectedRevision:s.expectedRevision,value:s.value},param:{key:s.key}}))},async reset(s){return await t.readJson(t.api.v1.preferences.ui[":key"].$delete({param:{key:s.key}}))}},async setMachineEnvironmentVariable(s){return t.readJson(t.api.v1.settings["machine-environment"].$post({json:s}))},async deleteMachineEnvironmentVariable(s){return t.readJson(t.api.v1.settings["machine-environment"].$delete({json:s}))},async machineEnvironment(){return t.readJson(t.api.v1.settings["machine-environment"].$get())},async replaceMachineEnvironment(s){return t.readJson(t.api.v1.settings["machine-environment"].$put({json:s}))},async attention(s){return t.readJson(t.api.v1.system.attention.$get({},...c(s?.signal)))},async aiServices(s){return t.readJson(t.api.v1.system["ai-services"].$get({},...c(s?.signal)))},async setAiServiceSelection(s){return t.readJson(t.api.v1.system["ai-services"].selection.$put({json:s}))},async testAiService(s){return t.readJson(t.api.v1.system["ai-services"].test.$post({json:s}))},async config(s){return t.readJson(t.api.v1.system.config.$get({},...c(s?.signal)))},async executionOptions(s={}){return fn(t,s)},async cliSkillsStatus(s={}){return t.readJson(t.api.v1.system["cli-skills"].$get({query:s.hostIds===void 0?{}:{hostIds:s.hostIds.join(",")}},...c(s.signal)))},async installCliSkills(s){return t.readJson(t.api.v1.system["cli-skills"].install.$post({json:s}))},async experimental_recordTelemetryEvent(s){return t.readJson(t.api.v1.system.telemetry.events.$post({json:s}))},async reloadConfig(){return t.readJson(t.api.v1.system.config.reload.$post())},async transcribeVoice(s){if(s.file.size===0)throw new Error("Audio file must not be empty");let i=new FormData;i.set("file",s.file),s.prompt!==void 0&&i.set("prompt",s.prompt);let a=t.baseUrl.replace(/\/$/u,""),l=await t.resolve(t.fetch(`${a}/api/v1/system/voice-transcription`,{method:"POST",body:i,signal:s.signal}));return xr.parse(await l.json())},async mobileAppReleases(){return t.readJson(t.api.v1.system["mobile-app-releases"].$get())},mobileAppDownloads(){return{...Li}},async updateExperiments(s){return t.readJson(t.api.v1.settings.experiments.$put({json:s}))},async updateGeneralSettings(s){return t.readJson(t.api.v1.settings.general.$put({json:s}))},async updateKeyboardSettings(s){return t.readJson(t.api.v1.settings.keyboard.$put({json:s}))},async providerStates(s={}){return t.readJson(t.api.v1.system.providers.state.$get({query:{environmentId:s.environmentId,hostId:s.hostId}},...c(s.signal)))},async usageLimits(s={}){return t.readJson(t.api.v1.system["usage-limits"].$get({query:{hostId:s.hostId,providerId:s.providerId,refresh:s.refresh===void 0?void 0:s.refresh?"true":"false"}},...c(s.signal)))},async version(s){return t.readJson(t.api.v1.system.version.$get({query:Ry(s)},...c(s?.signal)))},async appUpdate(s){return t.readJson(t.api.v1.system["app-update"].$get({query:Ty(s)},...c(s?.signal)))},async applyAppUpdate(s){return t.readJson(t.api.v1.system["app-update"].apply.$post({json:s}))},async acknowledgeAppUpdate(s){return t.readJson(t.api.v1.system["app-update"].acknowledge.$post({json:s}))},async experimental_cliCommand(s){return t.readJson(t.api.v1.system["cli-command"].$get({},...c(s?.signal)))},async experimental_installCliCommand(){return t.readJson(t.api.v1.system["cli-command"].install.$post({}))},async experimental_removeCliCommand(){return t.readJson(t.api.v1.system["cli-command"].remove.$post({}))}}}function Kl(n){switch(n.kind){case"thread":if("environmentId"in n||"hostId"in n||"cwd"in n)throw new Error("Thread terminal scope cannot include environment or host selectors.");return;case"environment":if("threadId"in n||"hostId"in n||"cwd"in n)throw new Error("Environment terminal scope cannot include thread or host selectors.");return;case"host_path":if("threadId"in n||"environmentId"in n)throw new Error("Host terminal scope cannot include thread or environment selectors.")}}function wy(n){switch(Kl(n),n.kind){case"thread":return{threadId:n.threadId};case"environment":return{environmentId:n.environmentId};case"host_path":return{hostId:n.hostId,...n.cwd===void 0?{}:{cwd:n.cwd}}}}function ky(n){switch(Kl(n),n.kind){case"thread":return{kind:"thread",threadId:n.threadId};case"environment":return{kind:"environment",environmentId:n.environmentId};case"host_path":return{kind:"host_path",hostId:n.hostId,cwd:n.cwd}}}function Py(n){return{...n.sinceSeq===void 0?{}:{sinceSeq:n.sinceSeq},...n.tailBytes===void 0?{}:{tailBytes:n.tailBytes},...n.limitChunks===void 0?{}:{limitChunks:n.limitChunks}}}function Vl(n){let{transport:t}=n;return{async close(i){return t.readJson(t.api.v1.terminals[":terminalId"].close.$post({param:{terminalId:i.terminalId},json:{mode:i.mode,reason:"user"}}))},create:i=>t.readJson(t.api.v1.terminals.$post({json:{cols:i.cols,id:i.id,rows:i.rows,start:i.start,target:ky(i.scope),title:i.title}})),get:i=>t.readJson(t.api.v1.terminals[":terminalId"].$get({param:{terminalId:i.terminalId}},...c(i.signal))),async input(i){return t.readJson(t.api.v1.terminals[":terminalId"].input.$post({param:{terminalId:i.terminalId},json:{dataBase64:i.dataBase64}}))},async list(i){return t.readJson(t.api.v1.terminals.$get({query:wy(i.scope)},...c(i.signal)))},async output(i){return t.readJson(t.api.v1.terminals[":terminalId"].output.$get({param:{terminalId:i.terminalId},query:Py(i)},...c(i.signal)))},async rename(i){return t.readJson(t.api.v1.terminals[":terminalId"].$patch({param:{terminalId:i.terminalId},json:{title:i.title}}))},async restart(i){return t.readJson(t.api.v1.terminals[":terminalId"].restart.$post({param:{terminalId:i.terminalId},json:{}}))},async resize(i){return t.readJson(t.api.v1.terminals[":terminalId"].resize.$post({param:{terminalId:i.terminalId},json:{cols:i.cols,rows:i.rows}}))}}}var Yl=1200*1e3,Zl=250,dt=class extends Error{target;threadId;constructor(t){super(Hy(t)),this.name="ThreadWaitTimeoutError",this.target=t.target,this.threadId=t.threadId}},Sn=class extends Error{currentStatus;target;threadId;constructor(t){super(`Thread ${t.threadId} is in status ${t.currentStatus} and will not reach idle by waiting alone. Inspect it with 'bb thread show ${t.threadId}' and recover by sending a follow-up.`),this.name="ThreadWaitUnreachableError",this.currentStatus=t.currentStatus,this.target=t.target,this.threadId=t.threadId}};function Ay(n){return{...n?.projectId?{projectId:n.projectId}:{},...n?.environmentId?{environmentId:n.environmentId}:{},...n?.hostId?{hostId:n.hostId}:{},...n?.parentThreadId?{parentThreadId:n.parentThreadId}:{},...n?.sourceThreadId?{sourceThreadId:n.sourceThreadId}:{},...n?.sectionId?{sectionId:n.sectionId}:{},...n?.originKind?{originKind:n.originKind}:{},...n?.originPluginId?{originPluginId:n.originPluginId}:{},...n?.threadIds===void 0?{}:{threadIds:n.threadIds.join(",")},...n?.archived===void 0?{}:{archived:n.archived?"true":"false"},...n?.unsectioned===void 0?{}:{unsectioned:n.unsectioned?"true":"false"},...n?.includeHidden===void 0?{}:{includeHidden:n.includeHidden?"true":"false"},...n?.limit===void 0?{}:{limit:String(n.limit)},...n?.offset===void 0?{}:{offset:String(n.offset)},...n?.hasParent===void 0?{}:{hasParent:n.hasParent?"true":"false"}}}function Iy(n){return{...n?.status===void 0?{}:{status:n.status},...n?.hostId===void 0?{}:{hostId:n.hostId},...n?.providerId===void 0?{}:{providerId:n.providerId},...n?.projectId===void 0?{}:{projectId:n.projectId},...n?.parentThreadId===void 0?{}:{parentThreadId:n.parentThreadId},...n?.groupBy===void 0?{}:{groupBy:n.groupBy}}}function Ey(n){return{title:n.title,sectionId:n.sectionId,parentThreadId:n.parentThreadId,model:n.model,reasoningLevel:n.reasoningLevel,sessionOptions:n.sessionOptions,visibility:n.visibility,parentNotifications:n.parentNotifications}}function Cy(n){return{input:n.input,mode:n.mode,model:n.model,permissionMode:n.permissionMode,reasoningLevel:n.reasoningLevel,senderThreadId:n.senderThreadId,originPluginId:n.originPluginId,serviceTier:n.serviceTier,pluginSubmission:n.pluginSubmission,executionInputSources:n.executionInputSources,sendAt:n.sendAt,compactFirst:n.compactFirst}}function jy(n){return{turnRequestId:n.turnRequestId??null,sendAt:n.sendAt??null,reason:n.reason??Xe}}function _y(n){return{...n?.threadId===void 0?{}:{threadId:n.threadId},...n?.waitHolder===void 0?{}:{waitHolder:n.waitHolder}}}function My(n){if(n.input!==void 0&&n.prompt!==void 0)throw new Error("Provide only one of input or prompt.");return n.input!==void 0?n.input:[{type:"text",text:n.prompt,mentions:[]}]}function Dy(n){let{input:t,origin:r,originKind:s,prompt:i,startedOnBehalfOf:a,...l}=n;return{...l,...n.pluginMetadata===void 0?{}:{pluginMetadata:Pt(n.pluginMetadata)},input:My(n),origin:r??"sdk",startedOnBehalfOf:a??null,originKind:s??null}}function Oy(n){return{...n,...n.pluginMetadata===void 0?{}:{pluginMetadata:Pt(n.pluginMetadata)},origin:n.origin??"sdk",visibility:n.visibility??"visible"}}function Ly(n){return{...n.afterSeq!==void 0?{afterSeq:n.afterSeq}:{},...n.beforeSeq!==void 0?{beforeSeq:n.beforeSeq}:{},...n.limit!==void 0?{limit:n.limit}:{},...n.order!==void 0?{order:n.order}:{},...n.types!==void 0?{types:n.types.join(",")}:{}}}function qy(n){return{...n.afterSeq!==void 0?{afterSeq:n.afterSeq}:{},type:n.type,waitMs:n.waitMs}}function Uy(n){return{limitPerGroup:n.limitPerGroup,query:n.query}}function By(n){return{...n.deferContent!==void 0?{deferContent:n.deferContent}:{},...n.includeNestedRows!==void 0?{includeNestedRows:n.includeNestedRows}:{},...n.summaryOnly!==void 0?{summaryOnly:n.summaryOnly}:{},...n.segmentLimit!==void 0?{segmentLimit:n.segmentLimit}:{},...n.beforeAnchorSeq!==void 0?{beforeAnchorSeq:n.beforeAnchorSeq}:{},...n.beforeAnchorId!==void 0?{beforeAnchorId:n.beforeAnchorId}:{},...n.afterSequence!==void 0?{afterSequence:n.afterSequence}:{}}}function Xl(n){return new Promise(t=>setTimeout(t,n))}function zy(n){let t=n.status!==void 0,r=n.event!==void 0;if(t&&r)throw new Error("Provide only one of status or event.");return r?{kind:"event",eventType:n.event??""}:{kind:"status",status:n.status??"idle"}}function Ny(n){let t=n.timeoutMs??Yl;if(!Number.isFinite(t)||t<0)throw new RangeError("Timeout must be a non-negative number of milliseconds.");let r=n.pollIntervalMs??Zl;if(!Number.isInteger(r)||r<1)throw new RangeError("Poll interval must be a positive integer number of milliseconds.");return{pollIntervalMs:r,target:zy(n),timeoutMs:t}}function Hy(n){return n.target.kind==="status"?`Timed out waiting for thread ${n.threadId} to reach status ${n.target.status}.`:`Timed out waiting for thread ${n.threadId} event ${n.target.eventType}.`}function Fy(n,t){return t.kind==="status"&&t.status==="idle"&&n==="error"}function ed(n){let{transport:t}=n,r=o=>t.readJson(t.api.v1.threads[":id"].$get({param:{id:o.threadId},...o.include===void 0?{}:{query:{include:o.include}}},...c(o.signal))),s=async o=>t.readJson(t.api.v1.threads[":id"]["archive-all"].$post({param:{id:o.threadId}})),i={async list(o){return t.readJson(t.api.v1.threads[":id"].events.$get({param:{id:o.threadId},query:Ly(o)},...c(o.signal)))},async wait(o){let g=await t.resolve(t.api.v1.threads[":id"].events.wait.$get({param:{id:o.threadId},query:qy(o)},...c(o.signal)));if(g.status===204)return null;let{parseThreadEventRow:b}=await import("./thread-event-parser-VC3WTCLZ.js");return b(await g.json())}};return{archive:s,archiveAll:s,async childSummary(o){return t.readJson(t.api.v1.threads[":id"]["child-summary"].$get({param:{id:o.threadId}},...c(o.signal)))},async conversationOutline(o){return t.readJson(t.api.v1.threads[":id"]["conversation-outline"].$get({param:{id:o.threadId},query:o.role===void 0?{}:{role:o.role}},...c(o.signal)))},async count(o){return t.readJson(t.api.v1.threads.count.$get({query:Iy(o)},...c(o?.signal)))},async listRunning(o){return t.readJson(t.api.v1.threads.running.$get({},...c(o?.signal)))},async defaultExecutionOptions(o){return t.readJson(t.api.v1.threads[":id"]["default-execution-options"].$get({param:{id:o.threadId}},...c(o.signal)))},async delete(o){return await t.readVoid(t.api.v1.threads[":id"].$delete({param:{id:o.threadId},json:{childThreadsConfirmed:o.childThreadsConfirmed}})),{ok:!0}},async editMessage(o){let{threadId:g,...h}=o;return t.readJson(t.api.v1.threads[":id"]["edit-message"].$post({param:{id:g},json:h}))},events:i,async fork(o){return t.readJson(t.api.v1.threads.fork.$post({json:Oy(o)}))},get:r,async experimental_listAncestors(o){return t.readJson(t.api.v1.threads.ancestors.$post({json:{threadIds:[...o.threadIds]}},...c(o.signal)))},async experimental_listDescendants(o){return t.readJson(t.api.v1.threads.descendants.$post({json:{threadIds:[...o.threadIds],...o.includeArchived===void 0?{}:{includeArchived:o.includeArchived},...o.includeHidden===void 0?{}:{includeHidden:o.includeHidden}}},...c(o.signal)))},async experimental_listPluginMetadata(o){return t.readJson(t.api.v1.threads["plugin-metadata"].$post({json:{pluginId:o.pluginId,threadIds:[...o.threadIds]}},...c(o.signal)))},async getPluginMetadata(o){return t.readJson(t.api.v1.threads[":id"]["plugin-metadata"].$get({param:{id:o.threadId},query:{pluginId:o.pluginId}},...c(o.signal)))},async updatePluginMetadata(o){return t.readJson(t.api.v1.threads[":id"]["plugin-metadata"].$patch({param:{id:o.threadId},json:{pluginId:o.pluginId,...o.set===void 0?{}:{set:Pt(o.set)},...o.remove===void 0?{}:{remove:o.remove}}},...c(o.signal)))},queue:{async list(o){return t.readJson(t.api.v1["queued-messages"].$get({query:_y(o)},...c(o?.signal)))}},interactions:{async cancel(o){return t.readJson(t.api.v1.threads[":id"].interactions[":interactionId"].cancel.$post({param:{id:o.threadId,interactionId:o.interactionId}}))},async get(o){return t.readJson(t.api.v1.threads[":id"].interactions[":interactionId"].$get({param:{id:o.threadId,interactionId:o.interactionId}},...c(o.signal)))},async list(o){return t.readJson(t.api.v1.threads[":id"].interactions.$get({param:{id:o.threadId}},...c(o.signal)))},async resolve(o){return t.readJson(t.api.v1.threads[":id"].interactions[":interactionId"].resolve.$post({param:{id:o.threadId,interactionId:o.interactionId},json:o.resolution}))},async respond(o){return t.readJson(t.api.v1.threads[":id"].interactions[":interactionId"].respond.$post({param:{id:o.threadId,interactionId:o.interactionId},json:{value:o.value}}))}},async list(o){return t.readJson(t.api.v1.threads.$get({query:Ay(o)},...c(o?.signal)))},async markRead(o){return t.readJson(t.api.v1.threads[":id"].read.$post({param:{id:o.threadId}},...c(o.signal)))},async markUnread(o){return t.readJson(t.api.v1.threads[":id"].unread.$post({param:{id:o.threadId}},...c(o.signal)))},async message(o){return t.readJson(t.api.v1.threads[":id"].messages[":seq"].$get({param:{id:o.threadId,seq:String(o.seq)},query:{...o.before===void 0?{}:{before:String(o.before)},...o.after===void 0?{}:{after:String(o.after)}}},...c(o.signal)))},async output(o){return t.readJson(t.api.v1.threads[":id"].output.$get({param:{id:o.threadId}},...c(o.signal)))},async open(o){return t.readJson(t.api.v1.threads[":id"].open.$post({param:{id:o.threadId},json:{...o.split===void 0?{}:{split:o.split},file:o.file}}))},async paneAction(o){return t.readJson(t.api.v1.threads[":id"]["pane-action"].$post({param:{id:o.threadId},json:{action:o.action}}))},async pin(o){return t.readJson(t.api.v1.threads[":id"].pin.$post({param:{id:o.threadId}}))},async promptHistory(o){return t.readJson(t.api.v1.threads[":id"]["prompt-history"].$get({param:{id:o.threadId},query:{limit:o.limit}},...c(o.signal)))},queuedMessages:{async create(o){let{threadId:g,...h}=o;return t.readJson(t.api.v1.threads[":id"]["queued-messages"].$post({param:{id:g},json:h}))},async delete(o){return await t.readVoid(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"].$delete({param:{id:o.threadId,queuedMessageId:o.queuedMessageId}})),{ok:!0}},async experimental_holdForEdit(o){return t.readJson(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"]["edit-hold"].$post({param:{id:o.threadId,queuedMessageId:o.queuedMessageId}}))},async experimental_releaseEditHold(o){return await t.readVoid(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"]["edit-hold"].$delete({param:{id:o.threadId,queuedMessageId:o.queuedMessageId}})),{ok:!0}},async list(o){return t.readJson(t.api.v1.threads[":id"]["queued-messages"].$get({param:{id:o.threadId}},...c(o.signal)))},async reorder(o){return t.readJson(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"].order.$patch({param:{id:o.threadId,queuedMessageId:o.queuedMessageId},json:{previousQueuedMessageId:o.previousQueuedMessageId,nextQueuedMessageId:o.nextQueuedMessageId,groupBoundaryQueuedMessageId:o.groupBoundaryQueuedMessageId}}))},async send(o){return t.readJson(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"].send.$post({param:{id:o.threadId,queuedMessageId:o.queuedMessageId},json:{mode:o.mode}}))},async setGroupBoundary(o){return t.readJson(t.api.v1.threads[":id"]["queued-messages"]["group-boundary"].$patch({param:{id:o.threadId},json:{expectedGroupedPrefixQueuedMessageIds:o.expectedGroupedPrefixQueuedMessageIds,groupBoundaryQueuedMessageId:o.groupBoundaryQueuedMessageId}}))},async update(o){let{queuedMessageId:g,threadId:h,...b}=o;return t.readJson(t.api.v1.threads[":id"]["queued-messages"][":queuedMessageId"].$patch({param:{id:h,queuedMessageId:g},json:b}))}},async reorderPinned(o){return t.readJson(t.api.v1.threads[":id"]["pin-order"].$patch({param:{id:o.threadId},json:{previousThreadId:o.previousThreadId,nextThreadId:o.nextThreadId}}))},async resolveMentions(o){return t.readJson(t.api.v1.threads["resolve-mentions"].$post({json:{threadIds:o.threadIds}},...c(o.signal)))},async search(o){return t.readJson(t.api.v1.threads.search.$get({query:Uy(o)},...c(o.signal)))},async send(o){return t.readJson(t.api.v1.threads[":id"].send.$post({param:{id:o.threadId},json:Cy(o)}))},async restoreEnvironment(o){return t.readJson(t.api.v1.threads[":id"]["restore-environment"].$post({param:{id:o.threadId}}))},async retry(o){return t.readJson(t.api.v1.threads[":id"].retry.$post({param:{id:o.threadId},json:jy(o)}))},async spawn(o){return t.readJson(t.api.v1.threads.$post({json:Dy(o)}))},async stop(o){return await t.readVoid(t.api.v1.threads[":id"].stop.$post({param:{id:o.threadId}})),{ok:!0}},async compact(o){return await t.readVoid(t.api.v1.threads[":id"].compact.$post({param:{id:o.threadId}})),{ok:!0}},async clearContext(o){return await t.readVoid(t.api.v1.threads[":id"].context.clear.$post({param:{id:o.threadId}})),{ok:!0}},async cancelPlan(o){return await t.readVoid(t.api.v1.threads[":id"].plan.cancel.$post({param:{id:o.threadId}})),{ok:!0}},async clearGoal(o){return await t.readVoid(t.api.v1.threads[":id"].goal.clear.$post({param:{id:o.threadId}})),{ok:!0}},tabs:{async get(o){let g=await t.readJson(t.api.v1.threads[":id"].tabs.$get({param:{id:o.threadId}},...c(o.signal)));return Er.parse(g)},async update(o){let g=await t.readJson(t.api.v1.threads[":id"].tabs.$put({param:{id:o.threadId},json:{expectedRevision:o.expectedRevision,tabs:o.tabs}}));return Er.parse(g)}},async context(o){return t.readJson(t.api.v1.threads[":id"].context.$get({param:{id:o.threadId}},...c(o.signal)))},async timeline(o){return t.readJson(t.api.v1.threads[":id"].timeline.$get({param:{id:o.threadId},query:By(o)},...c(o.signal)))},async timelineTurnSummaryDetails(o){return t.readJson(t.api.v1.threads[":id"].timeline["turn-summary-details"].$get({param:{id:o.threadId},query:{turnId:o.turnId,sourceSeqStart:o.sourceSeqStart,sourceSeqEnd:o.sourceSeqEnd,...o.beforeCursor===void 0?{}:{beforeCursor:o.beforeCursor},...o.deferContent===void 0?{}:{deferContent:o.deferContent},...o.itemId===void 0?{}:{itemId:o.itemId}}},...c(o.signal)))},async storageFiles(o){return t.readJson(t.api.v1.threads[":id"]["thread-storage"].files.$get({param:{id:o.threadId},query:{query:o.query,limit:o.limit}},...c(o.signal)))},async storageLocation(o){return t.readJson(t.api.v1.threads[":id"]["thread-storage"].location.$get({param:{id:o.threadId}},...c(o.signal)))},async storagePaths(o){return t.readJson(t.api.v1.threads[":id"]["thread-storage"].paths.$get({param:{id:o.threadId},query:{query:o.query,limit:o.limit,includeFiles:o.includeFiles,includeDirectories:o.includeDirectories}},...c(o.signal)))},async unarchive(o){return await t.readVoid(t.api.v1.threads[":id"].unarchive.$post({param:{id:o.threadId}})),{ok:!0}},async unpin(o){return t.readJson(t.api.v1.threads[":id"].unpin.$post({param:{id:o.threadId}}))},async update(o){return t.readJson(t.api.v1.threads[":id"].$patch({param:{id:o.threadId},json:Ey(o)}))},async wait(o){let{pollIntervalMs:g,target:h,timeoutMs:b}=Ny(o),y=Date.now()+b;for(;;){if(h.kind==="status"){let v=await r({signal:o.signal,threadId:o.threadId});if(v.status===h.status)return{matched:!0,target:h,thread:v,threadId:o.threadId};if(Fy(v.status,h))throw new Sn({currentStatus:v.status,target:h,threadId:o.threadId});if(Date.now()>=y)throw new dt({target:h,threadId:o.threadId});await Xl(g);continue}let d=Math.max(0,y-Date.now()),u=Math.floor(Math.min(d,3e4)),f=await i.wait({signal:o.signal,threadId:o.threadId,type:h.eventType,waitMs:String(u)});if(f!==null)return{event:f,matched:!0,target:h,threadId:o.threadId};if(Date.now()>=y)throw new dt({target:h,threadId:o.threadId});await Xl(g)}}}}function td(n){let{transport:t}=n;return{async create(r){let s=await t.readJson(t.api.v1["thread-sections"].$post({json:r}));return Dt.parse(s)},async delete(r){let s=await t.readJson(t.api.v1["thread-sections"].$delete({json:r}));return ar.parse(s)},async list(r){let s=await t.readJson(t.api.v1["thread-sections"].$get({},...c(r?.signal)));return Dt.array().parse(s)},async update(r){let s=await t.readJson(t.api.v1["thread-sections"].$patch({json:r}));return ar.parse(s)}}}function nd(n){let t={transport:n.transport},r=Pl({transport:n.transport}),s={experimental_desktopBrowsers:ql(t),experimental_promptHistory:Wl(t),experimental_server:Nl(t),environments:Ul(t),files:Bl(t),hosts:zl(t),subscribe(i){return r.subscribe(i)},projects:Hl(t),plugins:ya(t),providers:Fl(t),skills:Ql(t),status:$l(t),system:Jl(t),terminals:Vl(t),theme:Gl(t),threadSections:td(t),threads:ed(t)};return"guide"in n?{...s,guide:n.guide}:s}var Wy="";function rd(n){let t=n.baseUrl??Wy,r=n.fetch??fetch;return{api:Fi(t,{fetch:r}).api,baseUrl:t,fetch:r,...n.realtimeUrl?{realtimeUrl:n.realtimeUrl}:{},runtime:n.runtime,websocket:n.websocket,readJson:Dl,readVoid:Ol,resolve:gn}}function sd(n){return n??ks()}function $y(n){let t=sd(n);return`http://${mo}:${t.BB_HOST_DAEMON_PORT}`}function Qy(n={}){return rd({baseUrl:n.baseUrl??sd(n.cliConfig).BB_SERVER_URL,fetch:n.fetch??Ml({timeoutMs:n.timeoutMs??_l}),realtimeUrl:n.realtimeUrl,runtime:"node",websocket:n.websocket??Al()})}function uE(n={}){return nd({context:n.context,guide:Ln(),transport:Qy(n)})}async function mE(n={}){try{let r=await bo(n.hostDaemonUrl??$y(n.cliConfig)).status.$get();return r.ok?(await r.json()).hostId:null}catch{return null}}export{od as a,wn as b,ad as c,Ps as d,ue as e,yt as f,Ms as g,In as h,Ad as i,pv as j,gv as k,Od as l,qd as m,Bs as n,Ud as o,yv as p,Nd as q,me as r,Tv as s,k as t,Pv as u,Xs as v,wt as w,B as x,Ue as y,ge as z,Ns as A,_v as B,Uv as C,Zn as D,yx as E,Mn as F,Ln as G,_u as H,Jx as I,ig as J,Kt as K,Ye as L,Ze as M,Rg as N,JP as O,Fg as P,Yl as Q,Zl as R,dt as S,Sn as T,Al as U,le as V,Mb as W,rs as X,Lb as Y,Ub as Z,zb as _,Nb as $,Hb as aa,hn as ba,uE as ca,mE as da};
|