@hachej/boring-workspace 0.1.17 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +36 -34
  2. package/dist/{FileTree-Dvaud3jU.js → FileTree-DHVB9rpk.js} +15 -15
  3. package/dist/{MarkdownEditor-sLkqTXDj.js → MarkdownEditor-L1KDH0bM.js} +1 -1
  4. package/dist/{WorkspaceLoadingState-zLzh1tGc.js → WorkspaceLoadingState-DYDxUYnx.js} +114 -110
  5. package/dist/WorkspaceProvider-CDPaAO5u.js +5971 -0
  6. package/dist/app-front.d.ts +94 -107
  7. package/dist/app-front.js +243 -233
  8. package/dist/app-server.d.ts +130 -15
  9. package/dist/app-server.js +1569 -304
  10. package/dist/{bootstrapServer-BreQ9QBc.d.ts → createInMemoryBridge-BDxDzihm.d.ts} +11 -26
  11. package/dist/manifest-CyNNdfYz.d.ts +58 -0
  12. package/dist/plugin.d.ts +199 -0
  13. package/dist/plugin.js +300 -0
  14. package/dist/server.d.ts +239 -4
  15. package/dist/server.js +901 -78
  16. package/dist/shared.d.ts +4 -112
  17. package/dist/surface-COYagY2m.d.ts +111 -0
  18. package/dist/testing.d.ts +19 -1
  19. package/dist/testing.js +2 -2
  20. package/dist/{agent-tool-DEtfQPVB.d.ts → ui-bridge-Gfh1MMgl.d.ts} +30 -30
  21. package/dist/workspace.css +36 -0
  22. package/dist/workspace.d.ts +165 -120
  23. package/dist/workspace.js +330 -377
  24. package/docs/INTERFACES.md +9 -9
  25. package/docs/PLUGIN_STRUCTURE.md +39 -145
  26. package/docs/PLUGIN_SYSTEM.md +355 -0
  27. package/docs/README.md +6 -1
  28. package/docs/plans/README.md +1 -0
  29. package/docs/plans/archive/HOT_RELOADABLE_AGENT_PLUGINS_PLAN.md +218 -0
  30. package/docs/plans/archive/RELOAD_PLUGGABILITY_PLAN.md +174 -0
  31. package/docs/plans/archive/UNIFIED_PLUGIN_SYSTEM_PLAN.md +769 -0
  32. package/package.json +11 -5
  33. package/dist/CommandPalette-CJHuTJlD.js +0 -5716
  34. package/docs/bridge.md +0 -135
  35. package/docs/panels.md +0 -102
  36. package/docs/plugins.md +0 -158
  37. /package/docs/plans/{MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md → archive/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md} +0 -0
@@ -43,20 +43,6 @@ export declare interface AgentTool {
43
43
  execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
44
44
  }
45
45
 
46
- export declare interface AgentToolOutput {
47
- /**
48
- * @deprecated Executable agent tools should be contributed by server
49
- * plugins. This output remains for migration only.
50
- */
51
- type: "agent-tool";
52
- id: string;
53
- tool: AgentTool;
54
- }
55
-
56
- export declare interface AgentToolRegistry {
57
- register(tool: AgentTool, pluginId: string): void;
58
- }
59
-
60
46
  export declare interface ArtifactPanel {
61
47
  id: string;
62
48
  component: string;
@@ -82,33 +68,106 @@ export declare interface ArtifactSurfacePaneProps {
82
68
  className?: string;
83
69
  }
84
70
 
85
- export declare interface BindingOutput {
86
- type: "binding";
87
- id: string;
88
- component: PluginBinding;
89
- }
90
-
91
71
  export declare function bindStore(store: WorkspaceStoreApi): void;
92
72
 
93
73
  export declare function bootstrap(options: BootstrapOptions): BootstrapResult;
94
74
 
95
75
  export declare interface BootstrapOptions {
96
76
  chatPanel: unknown;
97
- plugins?: WorkspaceFrontPlugin[];
98
- defaults?: WorkspaceFrontPlugin[];
77
+ plugins?: BoringFrontFactoryWithId[];
78
+ defaults?: BoringFrontFactoryWithId[];
99
79
  excludeDefaults?: string[];
100
80
  registries: {
101
81
  panels: PanelRegistryLike;
102
82
  commands: CommandRegistryLike;
103
83
  catalogs: CatalogRegistryLike;
104
84
  surfaceResolvers?: SurfaceResolverRegistryLike;
105
- agentTools?: AgentToolRegistry;
106
85
  };
107
86
  }
108
87
 
109
88
  export declare interface BootstrapResult {
110
89
  registered: string[];
111
- systemPromptAppend: string;
90
+ plugins: CapturedFrontPlugin[];
91
+ }
92
+
93
+ declare interface BoringFrontAPI {
94
+ registerProvider(registration: BoringFrontProviderRegistration): void;
95
+ registerBinding(registration: BoringFrontBindingRegistration): void;
96
+ registerCatalog(registration: CatalogConfig): void;
97
+ registerPanel<T = unknown>(registration: BoringFrontPanelRegistration<T>): void;
98
+ registerPanelCommand(registration: BoringFrontPanelCommandRegistration): void;
99
+ registerLeftTab<T = LeftTabParams>(registration: BoringFrontLeftTabRegistration<T>): void;
100
+ registerSurfaceResolver(registration: BoringFrontSurfaceResolverRegistration): void;
101
+ }
102
+
103
+ declare interface BoringFrontBindingRegistration {
104
+ id: string;
105
+ component: PluginBinding;
106
+ }
107
+
108
+ declare type BoringFrontFactory = (api: BoringFrontAPI) => void | Promise<void>;
109
+
110
+ /**
111
+ * A `BoringFrontFactory` that carries its own plugin id (and optional
112
+ * label) as static properties. Produced by `definePlugin({ ... })` and used
113
+ * directly by `WorkspaceProvider.plugins`.
114
+ */
115
+ declare type BoringFrontFactoryWithId = BoringFrontFactory & {
116
+ pluginId: string;
117
+ pluginLabel?: string;
118
+ };
119
+
120
+ declare interface BoringFrontLeftTabRegistration<T = LeftTabParams> {
121
+ id: string;
122
+ title: string;
123
+ panelId: string;
124
+ icon?: ComponentType<{
125
+ className?: string;
126
+ }>;
127
+ component?: PanelConfig<T>["component"];
128
+ lazy?: boolean;
129
+ chromeless?: boolean;
130
+ requiresCapabilities?: string[];
131
+ source?: string;
132
+ }
133
+
134
+ declare interface BoringFrontPanelCommandRegistration {
135
+ id: string;
136
+ title: string;
137
+ panelId?: string;
138
+ run?: () => void;
139
+ keywords?: string[];
140
+ shortcut?: string;
141
+ when?: () => boolean;
142
+ }
143
+
144
+ declare interface BoringFrontPanelRegistration<T = unknown> {
145
+ id: string;
146
+ component: ComponentType<PaneProps<T>> | (() => Promise<{
147
+ default: ComponentType<PaneProps<T>>;
148
+ }>);
149
+ label?: string;
150
+ icon?: ComponentType<{
151
+ className?: string;
152
+ }>;
153
+ placement?: string;
154
+ requiresCapabilities?: string[];
155
+ essential?: boolean;
156
+ lazy?: boolean;
157
+ chromeless?: boolean;
158
+ source?: string;
159
+ }
160
+
161
+ declare interface BoringFrontProviderRegistration {
162
+ id: string;
163
+ component: PluginProvider;
164
+ }
165
+
166
+ declare interface BoringFrontSurfaceResolverRegistration {
167
+ id?: string;
168
+ kind: string;
169
+ source?: string;
170
+ resolve: (request: SurfaceOpenRequest) => SurfacePanelResolution | null | undefined;
112
171
  }
113
172
 
114
173
  export declare interface BridgeClient {
@@ -173,6 +232,22 @@ export declare function buildChatLayout(props?: ChatLayoutProps): LayoutConfig;
173
232
 
174
233
  export declare function buildIdeLayout(props?: IdeLayoutProps): LayoutConfig;
175
234
 
235
+ declare interface CapturedBoringFrontRegistrations {
236
+ providers: BoringFrontProviderRegistration[];
237
+ bindings: BoringFrontBindingRegistration[];
238
+ catalogs: CatalogConfig[];
239
+ panels: BoringFrontPanelRegistration<any>[];
240
+ panelCommands: BoringFrontPanelCommandRegistration[];
241
+ leftTabs: BoringFrontLeftTabRegistration<any>[];
242
+ surfaceResolvers: BoringFrontSurfaceResolverRegistration[];
243
+ }
244
+
245
+ declare interface CapturedFrontPlugin {
246
+ id: string;
247
+ label?: string;
248
+ registrations: CapturedBoringFrontRegistrations;
249
+ }
250
+
176
251
  export declare type CatalogAdapter = {
177
252
  search(args: CatalogSearchArgs): Promise<CatalogSearchResult>;
178
253
  fetchFacets?(args: CatalogFacetsArgs): Promise<CatalogFacets>;
@@ -211,11 +286,6 @@ export declare type CatalogFacetValue = {
211
286
  count: number;
212
287
  };
213
288
 
214
- export declare interface CatalogOutput {
215
- type: "catalog";
216
- catalog: CatalogConfig;
217
- }
218
-
219
289
  export declare class CatalogRegistry {
220
290
  private catalogs;
221
291
  private listeners;
@@ -225,6 +295,15 @@ export declare class CatalogRegistry {
225
295
  register(config: CatalogConfig, sourcePluginId: string): void;
226
296
  unregister(id: string): void;
227
297
  unregisterByPluginId(pluginId: string): void;
298
+ /**
299
+ * Atomic replace by pluginId: drop owned catalogs and register the new
300
+ * set in one emit. Pi parity for reload semantics.
301
+ *
302
+ * Collision policy: a new catalog id already owned by a DIFFERENT pluginId
303
+ * is skipped with a warning — same posture as `register`'s warnOnDuplicate
304
+ * but never silently overwriting another plugin's contribution.
305
+ */
306
+ replaceByPluginId(pluginId: string, catalogs: CatalogConfig[]): void;
228
307
  list(): readonly CatalogConfig[];
229
308
  get(id: string): CatalogConfig | undefined;
230
309
  subscribe: (cb: () => void) => (() => void);
@@ -326,11 +405,6 @@ export declare interface CommandConfig {
326
405
  pluginId?: string;
327
406
  }
328
407
 
329
- export declare interface CommandOutput {
330
- type: "command";
331
- command: CommandConfig;
332
- }
333
-
334
408
  export declare function CommandPalette(_props?: CommandPaletteProps): JSX.Element;
335
409
 
336
410
  export declare type CommandPaletteProps = Record<string, never>;
@@ -342,6 +416,14 @@ export declare class CommandRegistry {
342
416
  registerCommand(config: CommandConfig): void;
343
417
  unregisterByPluginId(pluginId: string): void;
344
418
  unregisterCommand(id: string): void;
419
+ /**
420
+ * Atomic replace by pluginId: drop owned commands and register the new
421
+ * set in one emit. Pi parity for reload semantics.
422
+ *
423
+ * Collision policy: a new command id already owned by a DIFFERENT pluginId
424
+ * is skipped with a warning — preserves cross-plugin isolation on reload.
425
+ */
426
+ replaceByPluginId(pluginId: string, commands: CommandConfig[]): void;
345
427
  getCommand(id: string): CommandConfig | undefined;
346
428
  getCommands(): CommandConfig[];
347
429
  getActiveCommands(): CommandConfig[];
@@ -363,31 +445,6 @@ export declare interface CommandResult {
363
445
  };
364
446
  }
365
447
 
366
- /**
367
- * Compose a parent plugin from smaller child plugins without introducing a new
368
- * enhancer/mixin lifecycle. Contributions are flattened into PluginOutput
369
- * values so normal plugin bootstrap remains the single registration path.
370
- */
371
- export declare function composePlugins(options: ComposePluginsOptions): WorkspaceFrontPlugin;
372
-
373
- export declare interface ComposePluginsOptions {
374
- id: string;
375
- label?: string;
376
- plugins: WorkspaceFrontPlugin[];
377
- outputs?: PluginOutput[];
378
- panels?: WorkspaceFrontPlugin["panels"];
379
- commands?: WorkspaceFrontPlugin["commands"];
380
- catalogs?: WorkspaceFrontPlugin["catalogs"];
381
- agentTools?: WorkspaceFrontPlugin["agentTools"];
382
- systemPrompt?: string;
383
- /**
384
- * When true (default), child contributions are registered as owned by the
385
- * composed parent plugin. When false, output contributions carry the child
386
- * plugin id so bootstrap can preserve child ownership in registries.
387
- */
388
- adoptOutputs?: boolean;
389
- }
390
-
391
448
  export declare function createBridge(store: StoreApi): WorkspaceBridge;
392
449
 
393
450
  export declare function createBridgeClient(options: BridgeClientOptions): BridgeClient;
@@ -430,8 +487,6 @@ export declare interface CreateWorkspaceStoreOptions {
430
487
  onLayoutVersionMismatch?: () => void;
431
488
  }
432
489
 
433
- export declare function defineFrontPlugin(spec: WorkspaceFrontPlugin): WorkspaceFrontPlugin;
434
-
435
490
  /**
436
491
  * Identity helper for type-safe panel registration. Pure runtime
437
492
  * passthrough — the value of this is forcing TypeScript to verify that
@@ -611,7 +666,7 @@ export declare const filesystemEvents: {
611
666
  readonly deleted: "filesystem:file.deleted";
612
667
  };
613
668
 
614
- export declare const filesystemPlugin: WorkspaceFrontPlugin;
669
+ export declare const filesystemPlugin: BoringFrontFactoryWithId;
615
670
 
616
671
  export declare function FileTree({ files, selectedPath, searchQuery, height, editing, revealPath, pendingPaths, onSelect, onExpand, onCollapse, onContextMenu, onSubmitEdit, onCancelEdit, onDragDrop, className, }: FileTreeProps): JSX.Element;
617
672
 
@@ -715,6 +770,8 @@ export declare interface FileTreeViewProps {
715
770
 
716
771
  export declare function formatShortcut(binding: Pick<ShortcutBinding, "key" | "mod" | "shift">): string;
717
772
 
773
+ export declare type FrontPluginHotReloadMode = "vite" | false;
774
+
718
775
  export declare function getFileIcon(filename: string): LucideIcon;
719
776
 
720
777
  export declare interface GroupConfig {
@@ -755,18 +812,6 @@ export declare interface LayoutConfig {
755
812
 
756
813
  export declare type LeftTabComponent = ComponentType<PaneProps<LeftTabParams>>;
757
814
 
758
- export declare interface LeftTabOutput<T = LeftTabParams> {
759
- type: "left-tab";
760
- id: string;
761
- title: string;
762
- icon?: PanelConfig<T>["icon"];
763
- component: PanelConfig<T>["component"];
764
- lazy?: PanelConfig<T>["lazy"];
765
- requiresCapabilities?: PanelConfig<T>["requiresCapabilities"];
766
- source?: PanelConfig<T>["source"];
767
- chromeless?: PanelConfig<T>["chromeless"];
768
- }
769
-
770
815
  export declare interface LeftTabParams {
771
816
  rootDir?: string;
772
817
  query?: string;
@@ -961,11 +1006,6 @@ export declare interface PanelLifecycleApi {
961
1006
  isActive: boolean;
962
1007
  }
963
1008
 
964
- export declare interface PanelOutput<T = any> {
965
- type: "panel";
966
- panel: PanelConfig<T>;
967
- }
968
-
969
1009
  export declare type PanelRegistration<T = any> = Omit<PanelConfig<T>, 'id'>;
970
1010
 
971
1011
  export declare class PanelRegistry {
@@ -974,15 +1014,33 @@ export declare class PanelRegistry {
974
1014
  private capabilities;
975
1015
  private listeners;
976
1016
  private snapshotCache;
1017
+ private lazyComponentCache;
1018
+ private wrapperComponentCache;
1019
+ private generation;
977
1020
  constructor(capabilities?: Record<string, boolean>);
978
1021
  register(id: string, config: PanelRegistration): void;
979
- unregisterByPluginId(pluginId: string): void;
1022
+ unregister(id: string): void;
1023
+ /**
1024
+ * Atomic replace: unregister all panels owned by `pluginId`, then register
1025
+ * the new set, in one emit cycle. Subscribers see exactly one intermediate
1026
+ * state — never an empty registry between unregister and re-register.
1027
+ *
1028
+ * Collision policy: a new registration whose id is already owned by a
1029
+ * DIFFERENT pluginId is skipped with a warning. Preserves cross-plugin
1030
+ * isolation during reload — a renamed plugin can't silently steal another
1031
+ * plugin's panel id. Teardown + rebuild as a single observable transition,
1032
+ * driven by the front-side SSE reload subscriber.
1033
+ */
1034
+ replaceByPluginId(pluginId: string, panels: PanelConfig[]): void;
980
1035
  get(id: string): PanelConfig | undefined;
981
1036
  has(id: string): boolean;
982
1037
  list(): PanelConfig[];
1038
+ listAll(): PanelConfig[];
983
1039
  getComponents(): Record<string, ComponentType<any>>;
984
1040
  subscribe: (cb: () => void) => (() => void);
985
1041
  getSnapshot: () => readonly PanelConfig[];
1042
+ private getWrappedComponent;
1043
+ private getLazyComponent;
986
1044
  private emit;
987
1045
  private filteredPanels;
988
1046
  private satisfiesCapabilities;
@@ -1060,14 +1118,12 @@ declare interface PluginErrorContextValue {
1060
1118
  reportPluginError: (error: PluginContributionError) => void;
1061
1119
  }
1062
1120
 
1063
- export declare type PluginErrorKind = "validation" | "duplicate-id" | "mount" | "contribution";
1121
+ export declare type PluginErrorKind = "duplicate-id" | "validation" | "runtime";
1064
1122
 
1065
1123
  export declare function PluginErrorProvider({ children }: {
1066
1124
  children: ReactNode;
1067
1125
  }): JSX.Element;
1068
1126
 
1069
- export declare type PluginOutput = LeftTabOutput | PanelOutput | CommandOutput | CatalogOutput | BindingOutput | ProviderOutput | SurfaceResolverOutput | AgentToolOutput;
1070
-
1071
1127
  export declare type PluginProvider = ComponentType<PluginProviderProps>;
1072
1128
 
1073
1129
  export declare interface PluginProviderProps {
@@ -1087,16 +1143,9 @@ declare interface Props {
1087
1143
  children?: ReactNode;
1088
1144
  }
1089
1145
 
1090
- export declare interface ProviderOutput {
1091
- type: "provider";
1092
- id: string;
1093
- component: PluginProvider;
1094
- }
1095
-
1096
1146
  declare interface RegisteredPluginMeta {
1097
1147
  id: string;
1098
1148
  label?: string;
1099
- systemPrompt?: string;
1100
1149
  }
1101
1150
 
1102
1151
  export declare function RegistryProvider({ panelRegistry, commandRegistry, catalogRegistry, surfaceResolverRegistry, children, }: RegistryProviderProps): JSX.Element;
@@ -1201,11 +1250,6 @@ export declare interface SurfaceResolverConfig {
1201
1250
  pluginId?: string;
1202
1251
  }
1203
1252
 
1204
- export declare interface SurfaceResolverOutput {
1205
- type: "surface-resolver";
1206
- resolver: SurfaceResolverConfig;
1207
- }
1208
-
1209
1253
  export declare type SurfaceResolverRegistration = Omit<SurfaceResolverConfig, "id">;
1210
1254
 
1211
1255
  export declare class SurfaceResolverRegistry {
@@ -1214,7 +1258,15 @@ export declare class SurfaceResolverRegistry {
1214
1258
  private listeners;
1215
1259
  private snapshotCache;
1216
1260
  register(id: string, config: SurfaceResolverRegistration): void;
1217
- unregisterByPluginId(pluginId: string): void;
1261
+ unregister(id: string): void;
1262
+ /**
1263
+ * Atomic replace by pluginId: drop owned resolvers and register the new
1264
+ * set in one emit. Pi parity for reload semantics.
1265
+ *
1266
+ * Collision policy: a new resolver id already owned by a DIFFERENT
1267
+ * pluginId is skipped with a warning.
1268
+ */
1269
+ replaceByPluginId(pluginId: string, resolvers: SurfaceResolverConfig[]): void;
1218
1270
  get(id: string): SurfaceResolverConfig | undefined;
1219
1271
  has(id: string): boolean;
1220
1272
  list(): SurfaceResolverConfig[];
@@ -1228,7 +1280,7 @@ export declare interface SurfaceResolverRegistryLike {
1228
1280
  register(id: string, config: SurfaceResolverRegistration): void;
1229
1281
  }
1230
1282
 
1231
- export declare function SurfaceShell({ rootDir, sidebarDefaultWidth, sidebarMinWidth, sidebarMaxWidth, storageKey, onReady, onChange, onClose, extraPanels, className, }: SurfaceShellProps): JSX.Element;
1283
+ export declare function SurfaceShell({ rootDir, sidebarDefaultWidth, sidebarMinWidth, sidebarMaxWidth, storageKey, onReady, onChange, onClose, extraPanels, defaultLeftTab, className, }: SurfaceShellProps): JSX.Element;
1232
1284
 
1233
1285
  export declare interface SurfaceShellApi {
1234
1286
  /** Open a file in the workbench. Idempotent — re-activates an existing pane for the same path. */
@@ -1272,6 +1324,7 @@ export declare interface SurfaceShellProps {
1272
1324
  * inside THIS surface (so a host can gate panels per shell instance).
1273
1325
  */
1274
1326
  extraPanels?: string[];
1327
+ defaultLeftTab?: string;
1275
1328
  className?: string;
1276
1329
  }
1277
1330
 
@@ -1623,6 +1676,7 @@ export declare interface WorkspaceChatPanelProps {
1623
1676
  export declare interface WorkspaceContextValue {
1624
1677
  chatPanel: WorkspaceChatPanelComponent | null;
1625
1678
  registeredPlugins: RegisteredPluginMeta[];
1679
+ debug: boolean;
1626
1680
  }
1627
1681
 
1628
1682
  export declare interface WorkspaceEventMap extends WorkspaceHostEventMap, WorkspacePluginEventMap {
@@ -1631,27 +1685,6 @@ export declare interface WorkspaceEventMap extends WorkspaceHostEventMap, Worksp
1631
1685
  /** Names that share a prefix can be filtered with `startsWith`. */
1632
1686
  export declare type WorkspaceEventName = keyof WorkspaceEventMap;
1633
1687
 
1634
- export declare interface WorkspaceFrontPlugin {
1635
- id: string;
1636
- label?: string;
1637
- /**
1638
- * Context prepended to the agent's system prompt at boot. Concatenated
1639
- * across all registered plugins (in registration order) and joined with
1640
- * double-newlines. Plain Markdown. ~200-500 chars recommended.
1641
- */
1642
- systemPrompt?: string;
1643
- panels?: PanelConfig[];
1644
- commands?: CommandConfig[];
1645
- catalogs?: CatalogConfig[];
1646
- bindings?: PluginBinding[];
1647
- /**
1648
- * @deprecated Executable agent tools should be contributed by server
1649
- * plugins. This field remains for migration only.
1650
- */
1651
- agentTools?: AgentTool[];
1652
- outputs?: PluginOutput[];
1653
- }
1654
-
1655
1688
  declare interface WorkspaceHostEventMap {
1656
1689
  /** Shared UI manipulation contract used by the agent stream and plugin bindings. */
1657
1690
  [WORKSPACE_UI_COMMAND_EVENT]: EventMeta & {
@@ -1728,12 +1761,16 @@ export declare interface WorkspacePluginEventMap {
1728
1761
  };
1729
1762
  }
1730
1763
 
1731
- export declare function WorkspaceProvider({ children, chatPanel, plugins, excludeDefaults, panels, commands, catalogs, capabilities, apiBaseUrl, authHeaders, apiTimeout, defaultTheme, onThemeChange, workspaceId, storageKey, persistenceEnabled, bridgeEndpoint, onAuthError, onOpenFile, }: WorkspaceProviderProps): JSX.Element;
1764
+ export declare function WorkspaceProvider({ children, chatPanel, plugins, excludeDefaults, panels, commands, catalogs, capabilities, apiBaseUrl, authHeaders, apiTimeout, defaultTheme, onThemeChange, workspaceId, storageKey, persistenceEnabled, bridgeEndpoint, onAuthError, onOpenFile, debug, frontPluginHotReload, }: WorkspaceProviderProps): JSX.Element;
1732
1765
 
1733
1766
  export declare interface WorkspaceProviderProps {
1734
1767
  children: ReactNode;
1735
1768
  chatPanel?: WorkspaceChatPanelComponent;
1736
- plugins?: WorkspaceFrontPlugin[];
1769
+ /**
1770
+ * Front plugin entries produced by `definePlugin({ id, ... })` from
1771
+ * `@hachej/boring-workspace/plugin`.
1772
+ */
1773
+ plugins?: BoringFrontFactoryWithId[];
1737
1774
  excludeDefaults?: string[];
1738
1775
  panels?: PanelConfig[];
1739
1776
  commands?: CommandConfig[];
@@ -1751,6 +1788,14 @@ export declare interface WorkspaceProviderProps {
1751
1788
  bridgeEndpoint?: string | null;
1752
1789
  onAuthError?: (statusCode: number) => void;
1753
1790
  onOpenFile?: (path: string) => void;
1791
+ debug?: boolean;
1792
+ /**
1793
+ * Hot-load dynamically discovered front plugin modules. The current
1794
+ * implementation relies on Vite's /@fs transform endpoint, so it defaults to
1795
+ * dev-only. Production hosts should keep this false until they provide their
1796
+ * own module asset endpoint.
1797
+ */
1798
+ frontPluginHotReload?: FrontPluginHotReloadMode;
1754
1799
  }
1755
1800
 
1756
1801
  export declare interface WorkspaceState {