@hachej/boring-workspace 0.1.59 → 0.1.61

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.
@@ -1 +1 @@
1
- .dv-shell{--dv-background-color: var(--background);--dv-paneview-header-border-color: var(--border);--dv-tabs-and-actions-container-font-size: .8125rem;--dv-tabs-and-actions-container-height: 52px;--dv-tab-close-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--dv-group-view-background-color: var(--background);--dv-tabs-and-actions-container-background-color: var(--background);--dv-activegroup-visiblepanel-tab-background-color: var(--background);--dv-activegroup-hiddenpanel-tab-background-color: var(--muted);--dv-inactivegroup-visiblepanel-tab-background-color: var(--background);--dv-inactivegroup-hiddenpanel-tab-background-color: var(--muted);--dv-activegroup-visiblepanel-tab-color: var(--foreground);--dv-activegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-inactivegroup-visiblepanel-tab-color: var(--foreground);--dv-inactivegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-tab-divider-color: transparent;--dv-drag-over-background-color: oklch(from var(--accent) l c h / .3);--dv-drag-over-border-color: var(--accent);--dv-separator-border: var(--border);color:var(--foreground);background-color:var(--background)}.dv-shell .dv-tabs-and-actions-container,.dv-shell .tabs-and-actions-container{background-color:var(--background)!important;border-bottom:1px solid oklch(from var(--border) l c h / .4);padding:6px 8px 0;gap:4px;align-items:flex-end}.dv-shell .dv-tabs-container,.dv-shell .tab-container{background-color:transparent!important;gap:4px;align-self:stretch;display:flex;align-items:flex-end}.workbench-dockview .dv-shell .dv-tabs-and-actions-container,.workbench-dockview .dv-shell .tabs-and-actions-container,.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{height:44px!important}.workbench-dockview[data-collapsed-sources=true] .dv-tabs-and-actions-container,.workbench-dockview[data-collapsed-sources=true] .tabs-and-actions-container{padding-left:44px!important}.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{padding-right:44px!important}.dv-shell .dv-tab,.dv-shell .tab{color:var(--muted-foreground)!important;background-color:transparent!important;border:1px solid transparent;border-top-left-radius:8px;border-top-right-radius:8px;transition:color .18s cubic-bezier(.22,1,.36,1),background-color .18s cubic-bezier(.22,1,.36,1),border-color .18s cubic-bezier(.22,1,.36,1);min-width:120px;max-width:220px;padding:0;height:34px;align-self:end;font-size:12.5px;letter-spacing:-.01em}.dv-shell .dv-tab:hover,.dv-shell .tab:hover{color:var(--foreground)!important;background-color:oklch(from var(--foreground) l c h / .04)!important}.dv-shell .dv-tab>*,.dv-shell .tab>*{width:100%;height:100%}.dv-shell .dv-tab.dv-active-tab,.dv-shell .tab.active-tab{color:var(--foreground)!important;background-color:var(--background)!important;border-color:oklch(from var(--border) l c h / .5);border-bottom-color:var(--background);margin-bottom:-1px;position:relative;z-index:1;font-weight:500}.dv-shell .dv-tab.dv-active-tab:before,.dv-shell .tab.active-tab:before{content:"";position:absolute;left:10px;right:10px;top:-1px;height:2px;background:var(--accent);border-radius:0 0 2px 2px;opacity:0;transition:opacity .2s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-tab.dv-active-tab:hover:before,.dv-shell .tab.active-tab:hover:before{opacity:.7}.dv-shell{--dv-sash-color: transparent;--dv-active-sash-color: transparent;--dv-active-sash-transition-delay: 0s}.dv-shell .sash-container .sash,.dv-shell .dv-sash-container .dv-sash{transition:box-shadow .16s cubic-bezier(.22,1,.36,1),background-color .16s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash{width:12px;margin-left:-4px}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash{height:12px;margin-top:-4px}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 5px 0 oklch(from var(--primary) l c h / .35),inset 6px 0 oklch(from var(--primary) l c h / .35)}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 0 5px oklch(from var(--primary) l c h / .35),inset 0 6px oklch(from var(--primary) l c h / .35)}.dv-shell .drop-target-dropzone>.drop-target-selection,.dv-shell .dv-drop-target-dropzone>.dv-drop-target-selection{background-color:oklch(from var(--primary) l c h / .15);border:2px dashed var(--primary);border-radius:calc(var(--radius) - 2px)}.dv-shell .watermark,.dv-shell .dv-watermark{color:var(--muted-foreground)}.dv-shell,.dv-shell .dv-dockview,.dv-shell .dv-groupview,.dv-shell .groupview,.dv-shell .groupview>.content-container,.dv-shell .dv-view-container,.dv-shell .view-container{background-color:var(--background)}.dv-shell .dv-groupview,.dv-shell .groupview{color:var(--foreground)}.dv-shell .right-actions-container,.dv-shell .left-actions-container,.dv-shell .dv-right-actions-container,.dv-shell .dv-left-actions-container{color:var(--muted-foreground);display:flex;align-items:center;align-self:stretch}.dv-shell .right-actions-container:hover,.dv-shell .left-actions-container:hover,.dv-shell .dv-right-actions-container:hover,.dv-shell .dv-left-actions-container:hover{color:var(--foreground)}.dv-shell .dv-drag-image{opacity:.85;border:1px solid var(--border);border-radius:calc(var(--radius) - 2px);box-shadow:0 4px 12px #00000026}.dv-chat-stage{--dv-tabs-and-actions-container-height: 32px;--dv-tabs-and-actions-container-font-size: .75rem;--dv-activegroup-visiblepanel-tab-background-color: transparent;--dv-activegroup-hiddenpanel-tab-background-color: transparent;--dv-inactivegroup-visiblepanel-tab-background-color: transparent;--dv-inactivegroup-hiddenpanel-tab-background-color: transparent}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container{border-bottom:none;padding:0;gap:0;align-items:stretch}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-tabs-container{width:100%}.dv-shell.dv-chat-stage .dv-tab,.dv-shell.dv-chat-stage .dv-tab.dv-active-tab{width:100%;height:100%;min-width:0;max-width:none;flex:1 1 auto;align-self:stretch;margin-bottom:0;padding:0;border:none;border-radius:0;background-color:transparent!important}.dv-shell.dv-chat-stage .dv-tab.dv-active-tab:before{content:none}.dv-chat-stage .dv-default-tab-action{display:none}.dv-chat-stage .dv-groupview{position:relative}.dv-chat-stage .dv-groupview:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;pointer-events:none;background:transparent;transition:background-color .22s cubic-bezier(.22,1,.36,1),box-shadow .22s cubic-bezier(.22,1,.36,1)}[data-boring-workspace-part=chat-pane-stage][data-multi-pane=true] .dv-groupview:not(.dv-active-group):after{background:oklch(from var(--foreground) l c h / .035)}
1
+ .dv-shell{--dv-background-color: var(--background);--dv-paneview-header-border-color: var(--border);--dv-tabs-and-actions-container-font-size: .8125rem;--dv-tabs-and-actions-container-height: 52px;--dv-tab-close-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--dv-group-view-background-color: var(--background);--dv-tabs-and-actions-container-background-color: var(--background);--dv-activegroup-visiblepanel-tab-background-color: var(--background);--dv-activegroup-hiddenpanel-tab-background-color: var(--muted);--dv-inactivegroup-visiblepanel-tab-background-color: var(--background);--dv-inactivegroup-hiddenpanel-tab-background-color: var(--muted);--dv-activegroup-visiblepanel-tab-color: var(--foreground);--dv-activegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-inactivegroup-visiblepanel-tab-color: var(--foreground);--dv-inactivegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-tab-divider-color: transparent;--dv-drag-over-background-color: oklch(from var(--accent) l c h / .3);--dv-drag-over-border-color: var(--accent);--dv-separator-border: var(--border);color:var(--foreground);background-color:var(--background)}.dv-shell .dv-tabs-and-actions-container,.dv-shell .tabs-and-actions-container{background-color:var(--background)!important;border-bottom:1px solid oklch(from var(--border) l c h / .4);padding:6px 8px 0;gap:4px;align-items:flex-end}.dv-shell .dv-tabs-container,.dv-shell .tab-container{background-color:transparent!important;gap:4px;align-self:stretch;display:flex;align-items:flex-end}.workbench-dockview .dv-shell .dv-tabs-and-actions-container,.workbench-dockview .dv-shell .tabs-and-actions-container,.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{height:44px!important}.workbench-dockview[data-left-block-collapsed=true] .dv-tabs-and-actions-container,.workbench-dockview[data-left-block-collapsed=true] .tabs-and-actions-container{padding-left:44px!important}[data-boring-workspace-part=plugin-tabs-shell][data-boring-state=collapsed] .dv-chat-stage .dv-tabs-and-actions-container,[data-boring-workspace-part=plugin-tabs-shell][data-boring-state=collapsed] .dv-chat-stage .tabs-and-actions-container{padding-left:48px!important}.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{padding-right:72px!important}.dv-shell .dv-tab,.dv-shell .tab{color:var(--muted-foreground)!important;background-color:transparent!important;border:1px solid transparent;border-top-left-radius:8px;border-top-right-radius:8px;transition:color .18s cubic-bezier(.22,1,.36,1),background-color .18s cubic-bezier(.22,1,.36,1),border-color .18s cubic-bezier(.22,1,.36,1);min-width:120px;max-width:220px;padding:0;height:34px;align-self:end;font-size:12.5px;letter-spacing:-.01em}.dv-shell .dv-tab:hover,.dv-shell .tab:hover{color:var(--foreground)!important;background-color:oklch(from var(--foreground) l c h / .04)!important}.dv-shell .dv-tab>*,.dv-shell .tab>*{width:100%;height:100%}.dv-shell .dv-tab.dv-active-tab,.dv-shell .tab.active-tab{color:var(--foreground)!important;background-color:var(--background)!important;border-color:oklch(from var(--border) l c h / .5);border-bottom-color:var(--background);margin-bottom:-1px;position:relative;z-index:1;font-weight:500}.dv-shell .dv-tab.dv-active-tab:before,.dv-shell .tab.active-tab:before{content:"";position:absolute;left:10px;right:10px;top:-1px;height:2px;background:var(--accent);border-radius:0 0 2px 2px;opacity:0;transition:opacity .2s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-tab.dv-active-tab:hover:before,.dv-shell .tab.active-tab:hover:before{opacity:.7}.dv-shell{--dv-sash-color: transparent;--dv-active-sash-color: transparent;--dv-active-sash-transition-delay: 0s}.dv-shell .sash-container .sash,.dv-shell .dv-sash-container .dv-sash{transition:box-shadow .16s cubic-bezier(.22,1,.36,1),background-color .16s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash{width:12px;margin-left:-4px}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash{height:12px;margin-top:-4px}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 5px 0 oklch(from var(--primary) l c h / .35),inset 6px 0 oklch(from var(--primary) l c h / .35)}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 0 5px oklch(from var(--primary) l c h / .35),inset 0 6px oklch(from var(--primary) l c h / .35)}.dv-shell .drop-target-dropzone>.drop-target-selection,.dv-shell .dv-drop-target-dropzone>.dv-drop-target-selection{background-color:oklch(from var(--primary) l c h / .15);border:2px dashed var(--primary);border-radius:calc(var(--radius) - 2px)}.dv-shell .watermark,.dv-shell .dv-watermark{color:var(--muted-foreground)}.dv-shell,.dv-shell .dv-dockview,.dv-shell .dv-groupview,.dv-shell .groupview,.dv-shell .groupview>.content-container,.dv-shell .dv-view-container,.dv-shell .view-container{background-color:var(--background)}.dv-shell .dv-groupview,.dv-shell .groupview{color:var(--foreground)}.dv-shell .right-actions-container,.dv-shell .left-actions-container,.dv-shell .dv-right-actions-container,.dv-shell .dv-left-actions-container{color:var(--muted-foreground);display:flex;align-items:center;align-self:stretch}.dv-shell .right-actions-container:hover,.dv-shell .left-actions-container:hover,.dv-shell .dv-right-actions-container:hover,.dv-shell .dv-left-actions-container:hover{color:var(--foreground)}.dv-shell .dv-drag-image{opacity:.85;border:1px solid var(--border);border-radius:calc(var(--radius) - 2px);box-shadow:0 4px 12px #00000026}.dv-chat-stage{--dv-tabs-and-actions-container-height: 32px;--dv-tabs-and-actions-container-font-size: .75rem;--dv-activegroup-visiblepanel-tab-background-color: transparent;--dv-activegroup-hiddenpanel-tab-background-color: transparent;--dv-inactivegroup-visiblepanel-tab-background-color: transparent;--dv-inactivegroup-hiddenpanel-tab-background-color: transparent}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container{height:var(--dv-tabs-and-actions-container-height);box-sizing:border-box;flex-shrink:0;border-bottom:none;padding:0;gap:0;align-items:stretch}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-scrollable,.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-tabs-container,.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-react-part{height:100%}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-tabs-container{width:100%;align-items:stretch}.dv-shell.dv-chat-stage .dv-tab,.dv-shell.dv-chat-stage .dv-tab.dv-active-tab{width:100%;height:100%;min-width:0;max-width:none;flex:1 1 auto;align-self:stretch;margin-bottom:0;padding:0;border:none;border-radius:0;background-color:transparent!important}.dv-shell.dv-chat-stage .dv-tab.dv-active-tab:before{content:none}.dv-chat-stage .dv-default-tab-action{display:none}.dv-chat-stage .dv-groupview{position:relative}.dv-chat-stage .dv-groupview:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;pointer-events:none;background:transparent;transition:background-color .22s cubic-bezier(.22,1,.36,1),box-shadow .22s cubic-bezier(.22,1,.36,1)}[data-boring-workspace-part=chat-pane-stage][data-multi-pane=true] .dv-groupview:not(.dv-active-group):after{background:oklch(from var(--foreground) l c h / .035)}
package/dist/events.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Tiny typed event bus. ~30 lines, no runtime deps.
3
3
  *
4
4
  * Design constraints (locked by reviewer feedback in
5
- * `docs/plans/UNIFIED_EVENT_BUS.md`):
5
+ * `packages/workspace/docs/plans/archive/UNIFIED_EVENT_BUS.md`):
6
6
  *
7
7
  * - Synchronous emit only. Slow subscribers fire-and-forget their own async work.
8
8
  * - Snapshot listeners before iterating so subscribe / unsubscribe
@@ -32,7 +32,7 @@ interface UiCommand {
32
32
  * All in-process cross-cutting signals flow through one typed map.
33
33
  * Adding a new event = adding a key here.
34
34
  *
35
- * See `docs/plans/UNIFIED_EVENT_BUS.md` for the design rationale and
35
+ * See `packages/workspace/docs/plans/archive/UNIFIED_EVENT_BUS.md` for the design rationale and
36
36
  * the planned future events. Those are intentionally NOT pre-declared
37
37
  * — they get added when their concrete emitter and consumer land in
38
38
  * the same step.
package/dist/plugin.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ComponentType, ReactNode } from 'react';
2
- import { P as PaneProps, a as PanelConfig, S as SurfaceOpenRequest, c as SurfacePanelResolution } from './surface-DmIalUmP.js';
3
- export { W as WORKSPACE_OPEN_PATH_SURFACE_KIND } from './surface-DmIalUmP.js';
2
+ import { P as PaneProps, a as PanelConfig, g as WorkspaceSourceProps, h as SurfaceResolverExample, S as SurfaceOpenRequest, c as SurfacePanelResolution } from './surface-CDklwi48.js';
3
+ export { W as WORKSPACE_OPEN_PATH_SURFACE_KIND, i as WorkspaceSourceOpenPanelConfig } from './surface-CDklwi48.js';
4
4
  export { B as BoringPackageBoringField, a as BoringPackagePiField, b as BoringPackagePiSource, c as BoringPackagePiSourceObject, d as BoringPluginManifestErrorCode, e as BoringPluginManifestIssue, f as BoringPluginManifestValidationResult, g as BoringPluginPackageJson, i as isSafePluginRelativePath, h as isValidBoringPluginId, v as validateBoringPluginManifest } from './manifest-C2vVgH_e.js';
5
5
  import { a as UiCommand, C as CommandResult, U as UiBridge } from './ui-bridge-BbuUZ5iC.js';
6
6
  import 'dockview-react';
@@ -66,19 +66,6 @@ interface CatalogConfig {
66
66
  onSelect: (row: CatalogRow) => void;
67
67
  pluginId?: string;
68
68
  }
69
- interface LeftTabParams {
70
- rootDir?: string;
71
- query?: string;
72
- searchQuery?: string;
73
- bridge?: unknown;
74
- chromeless?: boolean;
75
- /** Optional DOM target for left-tab toolbar actions owned by the pane. */
76
- chromeActionsElement?: Element | null;
77
- revealFileTreeRequest?: {
78
- path: string;
79
- seq: number;
80
- } | null;
81
- }
82
69
 
83
70
  interface BoringFrontPanelRegistration<T = unknown> {
84
71
  id: string;
@@ -89,7 +76,7 @@ interface BoringFrontPanelRegistration<T = unknown> {
89
76
  icon?: ComponentType<{
90
77
  className?: string;
91
78
  }>;
92
- placement?: string;
79
+ placement?: PanelConfig["placement"];
93
80
  requiresCapabilities?: string[];
94
81
  essential?: boolean;
95
82
  lazy?: boolean;
@@ -97,6 +84,21 @@ interface BoringFrontPanelRegistration<T = unknown> {
97
84
  supportsFullPage?: boolean;
98
85
  source?: string;
99
86
  }
87
+ interface BoringFrontWorkspaceSourceRegistration<T = unknown> {
88
+ id: string;
89
+ component: ComponentType<WorkspaceSourceProps<T>> | (() => Promise<{
90
+ default: ComponentType<WorkspaceSourceProps<T>>;
91
+ }>);
92
+ label?: string;
93
+ icon?: ComponentType<{
94
+ className?: string;
95
+ }>;
96
+ requiresCapabilities?: string[];
97
+ lazy?: boolean;
98
+ chromeless?: boolean;
99
+ defaultPanelId?: string;
100
+ source?: string;
101
+ }
100
102
  interface BoringFrontPanelCommandRegistration {
101
103
  id: string;
102
104
  title: string;
@@ -106,19 +108,6 @@ interface BoringFrontPanelCommandRegistration {
106
108
  shortcut?: string;
107
109
  when?: () => boolean;
108
110
  }
109
- interface BoringFrontLeftTabRegistration<T = LeftTabParams> {
110
- id: string;
111
- title: string;
112
- panelId: string;
113
- icon?: ComponentType<{
114
- className?: string;
115
- }>;
116
- component?: PanelConfig<T>["component"];
117
- lazy?: boolean;
118
- chromeless?: boolean;
119
- requiresCapabilities?: string[];
120
- source?: string;
121
- }
122
111
  interface BoringFrontProviderRegistration {
123
112
  id: string;
124
113
  component: PluginProvider;
@@ -130,6 +119,11 @@ interface BoringFrontBindingRegistration {
130
119
  interface BoringFrontSurfaceResolverRegistration {
131
120
  id?: string;
132
121
  kind: string;
122
+ title?: string;
123
+ description?: string;
124
+ targetHint?: string;
125
+ examples?: SurfaceResolverExample[];
126
+ metaSchema?: Record<string, unknown>;
133
127
  source?: string;
134
128
  resolve: (request: SurfaceOpenRequest) => SurfacePanelResolution | null | undefined;
135
129
  }
@@ -143,8 +137,8 @@ interface BoringFrontAPI {
143
137
  registerBinding(registration: BoringFrontBindingRegistration): void;
144
138
  registerCatalog(registration: CatalogConfig): void;
145
139
  registerPanel<T = unknown>(registration: BoringFrontPanelRegistration<T>): void;
140
+ registerWorkspaceSource<T = unknown>(registration: BoringFrontWorkspaceSourceRegistration<T>): void;
146
141
  registerPanelCommand(registration: BoringFrontPanelCommandRegistration): void;
147
- registerLeftTab<T = LeftTabParams>(registration: BoringFrontLeftTabRegistration<T>): void;
148
142
  registerSurfaceResolver(registration: BoringFrontSurfaceResolverRegistration): void;
149
143
  registerToolRenderer(registration: BoringFrontToolRendererRegistration): void;
150
144
  }
@@ -169,8 +163,8 @@ interface DefinePluginConfig {
169
163
  id: string;
170
164
  label?: string;
171
165
  panels?: ReadonlyArray<BoringFrontPanelRegistration<any>>;
166
+ workspaceSources?: ReadonlyArray<BoringFrontWorkspaceSourceRegistration<any>>;
172
167
  commands?: ReadonlyArray<BoringFrontPanelCommandRegistration>;
173
- leftTabs?: ReadonlyArray<BoringFrontLeftTabRegistration<any>>;
174
168
  surfaceResolvers?: ReadonlyArray<BoringFrontSurfaceResolverRegistration>;
175
169
  providers?: ReadonlyArray<BoringFrontProviderRegistration>;
176
170
  bindings?: ReadonlyArray<BoringFrontBindingRegistration>;
@@ -196,8 +190,8 @@ interface CapturedBoringFrontRegistrations {
196
190
  bindings: BoringFrontBindingRegistration[];
197
191
  catalogs: CatalogConfig[];
198
192
  panels: BoringFrontPanelRegistration<any>[];
193
+ workspaceSources: BoringFrontWorkspaceSourceRegistration<any>[];
199
194
  panelCommands: BoringFrontPanelCommandRegistration[];
200
- leftTabs: BoringFrontLeftTabRegistration<any>[];
201
195
  surfaceResolvers: BoringFrontSurfaceResolverRegistration[];
202
196
  toolRenderers: BoringFrontToolRendererRegistration[];
203
197
  }
@@ -277,4 +271,4 @@ declare function openPanel(args: OpenPanelArgs): Promise<CommandResult>;
277
271
  */
278
272
  declare function notify(msg: string, level?: "info" | "warn" | "error"): Promise<CommandResult>;
279
273
 
280
- export { type BoringFrontAPI, type BoringFrontBindingRegistration, type BoringFrontFactory, type BoringFrontFactoryWithId, type BoringFrontLeftTabRegistration, type BoringFrontPanelCommandRegistration, type BoringFrontPanelRegistration, type BoringFrontProviderRegistration, type BoringFrontSetup, type BoringFrontSurfaceResolverRegistration, type CapturedBoringFrontRegistrations, type CapturedFrontPlugin, type CapturingBoringFrontAPIHandle, type DefinePluginConfig, NoWorkspaceUiBridgeError, type OpenPanelArgs, PaneProps, captureFrontPlugin, createCapturingBoringFrontAPI, definePlugin, execWorkspaceUi, getWorkspaceUiBridge, notify, openPanel };
274
+ export { type BoringFrontAPI, type BoringFrontBindingRegistration, type BoringFrontFactory, type BoringFrontFactoryWithId, type BoringFrontPanelCommandRegistration, type BoringFrontPanelRegistration, type BoringFrontProviderRegistration, type BoringFrontSetup, type BoringFrontSurfaceResolverRegistration, type BoringFrontWorkspaceSourceRegistration, type CapturedBoringFrontRegistrations, type CapturedFrontPlugin, type CapturingBoringFrontAPIHandle, type DefinePluginConfig, NoWorkspaceUiBridgeError, type OpenPanelArgs, PaneProps, WorkspaceSourceProps, captureFrontPlugin, createCapturingBoringFrontAPI, definePlugin, execWorkspaceUi, getWorkspaceUiBridge, notify, openPanel };
package/dist/plugin.js CHANGED
@@ -13,7 +13,7 @@ function definePlugin(config) {
13
13
  if (typeof config !== "object" || config === null) {
14
14
  if (typeof config === "string" || typeof config === "function") {
15
15
  throw new Error(
16
- "definePlugin now takes a single declarative config object: definePlugin({ id, label?, panels, commands, leftTabs, surfaceResolvers, setup? }). The legacy positional form was removed \u2014 use the new shape."
16
+ "definePlugin now takes a single declarative config object: definePlugin({ id, label?, panels, commands, surfaceResolvers, setup? }). The legacy positional form was removed \u2014 use the new shape."
17
17
  );
18
18
  }
19
19
  throw new Error("definePlugin: expected a config object");
@@ -23,8 +23,8 @@ function definePlugin(config) {
23
23
  }
24
24
  const factory = (api) => {
25
25
  for (const panel of config.panels ?? []) api.registerPanel(panel);
26
+ for (const source of config.workspaceSources ?? []) api.registerWorkspaceSource(source);
26
27
  for (const command of config.commands ?? []) api.registerPanelCommand(command);
27
- for (const tab of config.leftTabs ?? []) api.registerLeftTab(tab);
28
28
  for (const resolver of config.surfaceResolvers ?? []) api.registerSurfaceResolver(resolver);
29
29
  for (const provider of config.providers ?? []) api.registerProvider(provider);
30
30
  for (const binding of config.bindings ?? []) api.registerBinding(binding);
@@ -55,8 +55,8 @@ function createCapturingBoringFrontAPI(options = {}) {
55
55
  const bindings = [];
56
56
  const catalogs = [];
57
57
  const panels = [];
58
+ const workspaceSources = [];
58
59
  const panelCommands = [];
59
- const leftTabs = [];
60
60
  const surfaceResolvers = [];
61
61
  const toolRenderers = [];
62
62
  const seen = /* @__PURE__ */ new Map();
@@ -86,25 +86,27 @@ function createCapturingBoringFrontAPI(options = {}) {
86
86
  catalogs.push(registration);
87
87
  },
88
88
  registerPanel(registration) {
89
+ if (registration.placement === "left-tab" || registration.placement === "workspace-source") {
90
+ throw new PluginError(
91
+ "validation",
92
+ `plugin "${options.pluginId ?? "<plugin>"}" uses removed panel placement "${registration.placement}" for "${registration.id}". Use registerWorkspaceSource / definePlugin({ workspaceSources }) instead.`
93
+ );
94
+ }
89
95
  claim("panel", registration.id);
90
96
  panels.push(registration);
91
97
  },
98
+ registerWorkspaceSource(registration) {
99
+ claim("workspace-source", registration.id);
100
+ workspaceSources.push(registration);
101
+ },
92
102
  registerPanelCommand(registration) {
93
103
  claim("command", registration.id);
94
104
  panelCommands.push(registration);
95
105
  },
96
- registerLeftTab(registration) {
97
- claim("left-tab", registration.id);
98
- leftTabs.push(registration);
99
- },
100
106
  registerSurfaceResolver(registration) {
101
107
  const id = registration.id ?? `${options.pluginId ?? "anon"}:${registration.kind}`;
102
108
  claim("surface-resolver", id);
103
- if (registration.id === void 0) {
104
- ;
105
- registration.id = id;
106
- }
107
- surfaceResolvers.push(registration);
109
+ surfaceResolvers.push({ ...registration, id });
108
110
  },
109
111
  registerToolRenderer(registration) {
110
112
  claim("tool-renderer", registration.id);
@@ -116,8 +118,8 @@ function createCapturingBoringFrontAPI(options = {}) {
116
118
  bindings: clone(bindings),
117
119
  catalogs: clone(catalogs),
118
120
  panels: clone(panels),
121
+ workspaceSources: clone(workspaceSources),
119
122
  panelCommands: clone(panelCommands),
120
- leftTabs: clone(leftTabs),
121
123
  surfaceResolvers: clone(surfaceResolvers),
122
124
  toolRenderers: clone(toolRenderers)
123
125
  };
package/dist/shared.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { C as CommandResult, a as UiCommand, b as UiState, W as WorkspaceBridge } from './ui-bridge-BbuUZ5iC.js';
2
2
  export { f as BridgeActorAttribution, g as BridgeActorKind, B as BridgeAuthContext, d as BridgeCallerClass, e as BridgeIdempotencyPolicy, h as BridgeRedactedActorRef, i as WorkspaceBridgeCallFailure, a as WorkspaceBridgeCallRequest, b as WorkspaceBridgeCallResponse, j as WorkspaceBridgeCallSuccess, c as WorkspaceBridgeError, k as WorkspaceBridgeErrorCode, l as WorkspaceBridgeFileAssetPointer, m as WorkspaceBridgeJsonValue, W as WorkspaceBridgeOperationDefinition, n as createWorkspaceBridgeError } from './workspace-bridge-rpc-A98RA5o6.js';
3
- export { C as CommandConfig, P as PaneProps, a as PanelConfig, b as PanelRegistration, S as SurfaceOpenRequest, c as SurfacePanelResolution, d as SurfaceResolverConfig, e as SurfaceResolverRegistration, W as WORKSPACE_OPEN_PATH_SURFACE_KIND, f as definePanel } from './surface-DmIalUmP.js';
3
+ export { C as CommandConfig, P as PaneProps, a as PanelConfig, b as PanelRegistration, S as SurfaceOpenRequest, c as SurfacePanelResolution, d as SurfaceResolverConfig, e as SurfaceResolverRegistration, W as WORKSPACE_OPEN_PATH_SURFACE_KIND, f as definePanel } from './surface-CDklwi48.js';
4
4
  export { A as AgentTool, J as JSONSchema, T as ToolExecContext, a as ToolResult } from './agent-tool-CB0RQyx9.js';
5
5
  import 'react';
6
6
  import 'dockview-react';
@@ -35,20 +35,35 @@ interface PaneProps<T = unknown> {
35
35
  /** Optional className forwarded to the pane's root element. */
36
36
  className?: string;
37
37
  }
38
+ interface WorkspaceSourceOpenPanelConfig {
39
+ id: string;
40
+ component: string;
41
+ title?: string;
42
+ params?: Record<string, unknown>;
43
+ }
44
+ /**
45
+ * Props for workspace source panes hosted in the left workspace rail.
46
+ * These are not Dockview panels: they receive only source-pane params and
47
+ * the explicit actions that the source host supports.
48
+ */
49
+ interface WorkspaceSourceProps<T = unknown> {
50
+ params: T;
51
+ className?: string;
52
+ openPanel?: (config: WorkspaceSourceOpenPanelConfig) => void;
53
+ }
54
+ type PanelPlacement = "left" | "center" | "right" | "bottom" | "shared-dockview" | "workspace-page" | "right-tab";
38
55
  interface PanelConfig<T = any> {
39
56
  id: string;
40
57
  title: string;
41
58
  icon?: ComponentType<{
42
59
  className?: string;
43
60
  }>;
44
- /** Placement hint: "left" | "center" | "right" | "bottom" | "left-tab" | "right-tab" */
45
- placement?: string;
61
+ /** Placement hint. Public plugin placements: "workspace-page" | "shared-dockview". */
62
+ placement?: PanelPlacement | string;
46
63
  requiresCapabilities?: string[];
47
64
  essential?: boolean;
48
65
  chromeless?: boolean;
49
66
  supportsFullPage?: boolean;
50
- /** Center-panel id opened when this config is used as a left-tab category. */
51
- defaultPanelId?: string;
52
67
  /** Source: "builtin" | "app" */
53
68
  source?: string;
54
69
  pluginId?: string;
@@ -105,7 +120,20 @@ interface SurfacePanelResolution {
105
120
  params?: Record<string, unknown>;
106
121
  score?: number;
107
122
  }
108
- interface SurfaceResolverConfig {
123
+ interface SurfaceResolverExample {
124
+ target: string;
125
+ label?: string;
126
+ meta?: Record<string, unknown>;
127
+ }
128
+ interface SurfaceResolverMetadata {
129
+ kind?: string;
130
+ title?: string;
131
+ description?: string;
132
+ targetHint?: string;
133
+ examples?: SurfaceResolverExample[];
134
+ metaSchema?: Record<string, unknown>;
135
+ }
136
+ interface SurfaceResolverConfig extends SurfaceResolverMetadata {
109
137
  id: string;
110
138
  resolve: (request: SurfaceOpenRequest) => SurfacePanelResolution | undefined;
111
139
  source?: string;
@@ -113,4 +141,4 @@ interface SurfaceResolverConfig {
113
141
  }
114
142
  type SurfaceResolverRegistration = Omit<SurfaceResolverConfig, "id">;
115
143
 
116
- export { type CommandConfig as C, type PaneProps as P, type SurfaceOpenRequest as S, WORKSPACE_OPEN_PATH_SURFACE_KIND as W, type PanelConfig as a, type PanelRegistration as b, type SurfacePanelResolution as c, type SurfaceResolverConfig as d, type SurfaceResolverRegistration as e, definePanel as f };
144
+ export { type CommandConfig as C, type PaneProps as P, type SurfaceOpenRequest as S, WORKSPACE_OPEN_PATH_SURFACE_KIND as W, type PanelConfig as a, type PanelRegistration as b, type SurfacePanelResolution as c, type SurfaceResolverConfig as d, type SurfaceResolverRegistration as e, definePanel as f, type WorkspaceSourceProps as g, type SurfaceResolverExample as h, type WorkspaceSourceOpenPanelConfig as i };
package/dist/testing.d.ts CHANGED
@@ -225,14 +225,12 @@ declare interface PanelConfig<T = any> {
225
225
  icon?: ComponentType<{
226
226
  className?: string;
227
227
  }>;
228
- /** Placement hint: "left" | "center" | "right" | "bottom" | "left-tab" | "right-tab" */
229
- placement?: string;
228
+ /** Placement hint. Public plugin placements: "workspace-page" | "shared-dockview". */
229
+ placement?: PanelPlacement | string;
230
230
  requiresCapabilities?: string[];
231
231
  essential?: boolean;
232
232
  chromeless?: boolean;
233
233
  supportsFullPage?: boolean;
234
- /** Center-panel id opened when this config is used as a left-tab category. */
235
- defaultPanelId?: string;
236
234
  /** Source: "builtin" | "app" */
237
235
  source?: string;
238
236
  pluginId?: string;
@@ -249,6 +247,8 @@ declare interface PanelConfig<T = any> {
249
247
  }>);
250
248
  }
251
249
 
250
+ declare type PanelPlacement = "left" | "center" | "right" | "bottom" | "shared-dockview" | "workspace-page" | "right-tab";
251
+
252
252
  declare type PanelRegistration<T = any> = Omit<PanelConfig<T>, 'id'>;
253
253
 
254
254
  declare class PanelRegistry {
package/dist/testing.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { jsx as Ba } from "react/jsx-runtime";
2
2
  import * as Pa from "react";
3
3
  import { createElement as is, useMemo as wn, useLayoutEffect as us, isValidElement as ss, cloneElement as ds, useSyncExternalStore as Gi } from "react";
4
- import { i as cs, w as fs, v as ps } from "./WorkspaceProvider-Bp1Sm40K.js";
5
- import { d as ms } from "./panel-DnvDNQac.js";
4
+ import { i as cs, O as fs, x as ps, v as ms } from "./WorkspaceProvider-kf-pjz6V.js";
6
5
  import * as bs from "react-dom/test-utils";
7
6
  import ka from "react-dom";
8
7
  import * as xn from "react-dom/client";
9
- import { bootClean as ov, openPaneViaBridge as lv, openWorkbench as iv } from "./testing-e2e.js";
8
+ import { bootClean as nv, openPaneViaBridge as ov, openWorkbench as lv } from "./testing-e2e.js";
10
9
  function vs() {
11
10
  return is(
12
11
  "div",
@@ -15,7 +14,7 @@ function vs() {
15
14
  );
16
15
  }
17
16
  const hs = [
18
- ms({
17
+ fs({
19
18
  id: "workspace-testing-default-panel",
20
19
  title: "Workspace Test Panel",
21
20
  component: vs,
@@ -208,7 +207,7 @@ function Es({
208
207
  globalThis.fetch = d;
209
208
  };
210
209
  }, [r]), /* @__PURE__ */ Ba("div", { "data-boring-workspace-testing": "", className: c === "dark" ? "dark" : void 0, children: /* @__PURE__ */ Ba(
211
- fs,
210
+ ps,
212
211
  {
213
212
  panels: u,
214
213
  apiBaseUrl: a,
@@ -216,7 +215,7 @@ function Es({
216
215
  defaultTheme: c,
217
216
  persistenceEnabled: !1,
218
217
  bridgeEndpoint: null,
219
- children: /* @__PURE__ */ Ba(ps, { apiBaseUrl: a, authHeaders: s, timeout: o, children: e })
218
+ children: /* @__PURE__ */ Ba(ms, { apiBaseUrl: a, authHeaders: s, timeout: o, children: e })
220
219
  }
221
220
  ) });
222
221
  }
@@ -10604,7 +10603,7 @@ if ((typeof process > "u" || !((Wi = process.env) != null && Wi.RTL_SKIP_AUTO_CL
10604
10603
  ve(e);
10605
10604
  });
10606
10605
  }
10607
- function Xb(e, r = {}) {
10606
+ function Jb(e, r = {}) {
10608
10607
  const {
10609
10608
  fixtures: t,
10610
10609
  bridge: a = xs(),
@@ -10642,7 +10641,7 @@ const Fb = () => {
10642
10641
  { id: "s5", title: "Old exploration", updatedAt: e - 960 * 60 * 6e4 }
10643
10642
  ];
10644
10643
  };
10645
- function Qb(e = {}) {
10644
+ function Xb(e = {}) {
10646
10645
  var c;
10647
10646
  const r = e.initial ?? Fb();
10648
10647
  let t = {
@@ -10671,7 +10670,7 @@ function Qb(e = {}) {
10671
10670
  }
10672
10671
  };
10673
10672
  }
10674
- function Zb(e) {
10673
+ function Qb(e) {
10675
10674
  return Gi(e.subscribe, e.getState, e.getState);
10676
10675
  }
10677
10676
  function jb() {
@@ -10702,7 +10701,7 @@ function Hb(e, r) {
10702
10701
  } catch {
10703
10702
  }
10704
10703
  }
10705
- function ev(e = {}) {
10704
+ function Zb(e = {}) {
10706
10705
  const r = e.storageKey ?? "workspace:sessions", t = e.initial ?? jb;
10707
10706
  let a = $b(r, t);
10708
10707
  const s = /* @__PURE__ */ new Set(), c = (o) => {
@@ -10733,7 +10732,7 @@ function ev(e = {}) {
10733
10732
  }
10734
10733
  };
10735
10734
  }
10736
- function rv(e) {
10735
+ function ev(e) {
10737
10736
  return Gi(e.subscribe, e.getState, e.getState);
10738
10737
  }
10739
10738
  const G = () => {
@@ -10808,7 +10807,7 @@ function Vb() {
10808
10807
  onDidActivePanelChange_: V.event
10809
10808
  };
10810
10809
  }
10811
- function tv(e) {
10810
+ function rv(e) {
10812
10811
  const r = e !== null && typeof e == "object" && "params" in e ? e : { params: e }, t = r.panelId ?? "test-panel", a = zb(t), s = Vb();
10813
10812
  return {
10814
10813
  params: r.params,
@@ -10822,15 +10821,15 @@ function tv(e) {
10822
10821
  }
10823
10822
  export {
10824
10823
  Es as TestWorkspaceProvider,
10825
- ov as bootClean,
10826
- ev as createLocalStorageSessions,
10824
+ nv as bootClean,
10825
+ Zb as createLocalStorageSessions,
10827
10826
  xs as createMockBridge,
10828
- tv as createMockPaneProps,
10827
+ rv as createMockPaneProps,
10829
10828
  Yi as createMockRegistry,
10830
- Qb as createMockSessions,
10831
- lv as openPaneViaBridge,
10832
- iv as openWorkbench,
10833
- Xb as renderPane,
10834
- rv as useLocalStorageSessions,
10835
- Zb as useMockSessions
10829
+ Xb as createMockSessions,
10830
+ ov as openPaneViaBridge,
10831
+ lv as openWorkbench,
10832
+ Jb as renderPane,
10833
+ ev as useLocalStorageSessions,
10834
+ Qb as useMockSessions
10836
10835
  };