From aad7f128bbcdacc1e5c8cffad5af5581216b2960 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Tue, 28 Jul 2026 01:11:12 -0500 Subject: [PATCH] feat(sdk): expose FloatingAnchor to plugins Plugins previously had to fake a floating pane by registering into a chrome slot and rendering position:fixed themselves, which broke inside any transformed ancestor and reimplemented drag, clamping, and persistence each time. --- apps/desktop/src/sdk/index.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/sdk/index.ts b/apps/desktop/src/sdk/index.ts index 285f843dcc2..8d28af45238 100644 --- a/apps/desktop/src/sdk/index.ts +++ b/apps/desktop/src/sdk/index.ts @@ -125,6 +125,12 @@ export { type RouteContribution, ROUTES_AREA, SIDEBAR_NAV_AREA, type SidebarNavC export type { StatusbarItem } from '@/app/shell/statusbar-controls' export type { TitlebarTool } from '@/app/shell/titlebar-controls' +/** Pane placement roles. `'floating'` is the one NON-tiling value: the pane is + * excluded from the layout tree and rendered as a fixed, draggable card above + * it — it takes no width from any zone, has no tab, and can't be docked. + * Pair it with `anchor` (spawn corner, default `'top-right'`) plus + * `width`/`height`. */ +export type { FloatingAnchor } from '@/components/pane-shell/tree/renderer/floating-rect' export { StatusDot, type StatusTone } from '@/components/status-dot' export { Badge } from '@/components/ui/badge' export { Button } from '@/components/ui/button' @@ -177,6 +183,9 @@ export { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' export { Textarea } from '@/components/ui/textarea' export { Tip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' export type { GatewayEventListener } from '@/contrib/events' + +// -- contracts ---------------------------------------------------------------- + export type { HermesPlugin, PluginContext, @@ -184,9 +193,6 @@ export type { PluginRestOptions, PluginStorage } from '@/contrib/plugin' - -// -- contracts ---------------------------------------------------------------- - /** Mount-scoped contribution: while the rendering component is mounted, its * children render in the target area's slot; unmount disposes it. Use for * page-owned chrome (a page's titlebar control leaves with the page) — @@ -215,12 +221,12 @@ export { type KeybindContribution, KEYBINDS_AREA } from '@/lib/keybinds/actions' * authors) + its translucent tag fill — so plugin-rendered identities read * the same hue as everywhere else. */ export { profileColor, profileColorSoft } from '@/lib/profile-color' + +export const PANES_AREA = 'panes' /** The shared client itself, for invalidation OUTSIDE React (e.g. a * `ctx.socket` frame invalidating a query). Inside components keep using * `useQueryClient`. */ export { queryClient } from '@/lib/query-client' - -export const PANES_AREA = 'panes' export const STATUSBAR_AREAS = { left: 'statusBar.left', right: 'statusBar.right' } as const export const TITLEBAR_AREAS = { center: 'titleBar.center', left: 'titleBar.left', right: 'titleBar.right' } as const